home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i024: Public lineprinter spooler package, Part11/16
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: papowell@julius.cs.umn.edu
- Posting-number: Volume 16, Issue 24
- Archive-name: plp/part11
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 11 (of 16)."
- # Contents: doc/PLP/11.t src/localprinter.c src/lpr_parms.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/PLP/11.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/PLP/11.t'\"
- else
- echo shar: Extracting \"'doc/PLP/11.t'\" \(15498 characters\)
- sed "s/^X//" >'doc/PLP/11.t' <<'END_OF_FILE'
- X.ig
- X$Header: 11.t,v 1.1 88/05/21 18:39:52 papowell Locked $
- X$log$
- X..
- X.bp
- X.NH 1
- Installation and Testing
- X.PP
- The following is a summary of the installation
- and test procedures for the PLP software.
- X.NH 2
- Source Files
- X.PP
- As distributed,
- all source and related files for the software have been
- collected under a common directory
- X$(PLP),
- The $(PLP) directory has the following structure.
- X.DS
- X.DT
- X.ta 12m +4n +4n
- X.L
- X.SM
- README -- brief summary
- Makefile -- calls {bin, filters, utilities}/Makefile
- bin/ -- directory for binaries and executables
- bin/Makefile -- Makefile for executables
- doc/ -- documentation source, this document
- filters/ -- output filters
- lint/ -- directory for lint output
- man/ -- man pages
- src/ -- source for lpd, lpr, lpc, etc.
- test/ -- test programs and files
- utilities/ -- source for pr, cpr and other handy print formatters.
- printcap/ -- a method to organize printcap entries
- X.DE
- X.NH 2
- Printcap And Printer Permissions Files
- X.PP
- The PLP software uses a different organization of printcap and permissions
- files than the Berkeley LPD.
- All of the PLP related control and informations files are gathered in
- X.L /usr/spool/lpd .
- XFor example:
- X.DS
- X.nf
- X.SM
- X.L
- X.ta 15n +4n +4n +4n 8i
- X.vs -2
- X.R
- X.LG
- X/usr/spool/lpd/printcap.<host> # printcap for <host>
- X/usr/spool/lpd/printer_perms.<host> # printer permissions for <host>
- X/usr/spool/lpd/lpd.lock.<host> # lpd daemon lock for <host>
- X/usr/spool/lpd/log.<host> # lpd daemon log for <host>
- X.vs +2
- X.LG
- X.R
- X.DE
- In a networked base file system,
- this allows a single spool directory to be shared among all the
- systems using PLP.
- In addition,
- only system which are performing unspooling operations will need to
- have an LPD daemon running.
- XFinally,
- care has been taken to ensure that all accesses to the shared files are
- done by
- user id
- X.L daemon .
- X.PP
- In order to update an existing system,
- all that needs to be done is to create a spool directory and
- provide the above files.
- The file
- X.L $(PLP)/test/printer_perms.all
- is a prototype printer permissions file that does not provide
- many restrictions.
- X.KF
- X.in +1i
- X.nf
- X.DT
- X.L
- X.SM
- X.vs -2
- X.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 8i
- X#!/bin/csh
- X# Creating the /usr/spool/lpd directory
- set h=<<<<host>>>>; # specify your host name
- mkdir /usr/spool/lpd
- ln -s /etc/printcap /usr/spool/lpd/printcap.${h}
- cp $(PLP)/test/printer_perms.all /usr/spool/lpd/printer_perms.${h}
- X.vs +2
- X.sp .5v
- X.R
- X.LG
- X.in -1i
- X.ce
- XFigure 11.1 Creating Directories
- X.KE
- X.NH 2
- Compilation and Installation
- X.PP
- The
- X.L bin
- directory is used to hold binaries.
- During the initial installation procedure,
- you should copy the
- X.L Makefile
- from the
- X.L src directory,
- and set any system dependent flags in the Makefile.
- The flags
- X.L IS_<system>
- are used to specify the system type,
- and cause conditional compilation of
- entries in the
- X.L src/lp.h
- file.
- After checking the flags and their implications,
- X.L "make all"
- can be used
- to compile and link the programs.
- X.PP
- As distributed,
- the
- X.L XPERIMENT
- compilation flag is set in the Makefile,
- and causes a test verion of the PLP softwar to be generated.
- It is strongly suggested you try the test or experimental version first,
- i.e.- compile with the XPERIMENT option enabled,
- and then try a fully functional version.
- X.NH 2
- Test Version
- X.PP
- A test version of the spooling software can be generated
- by compiling with the XPERIMENT flag set.
- This causes
- X.L /tmp/printcap.<host>,
- X.L /tmp/printer_perms.<host>,
- and a non-priviledged INET port
- to be used,
- rather than
- X.L /usr/spool/lpd/printcap.<host>,
- and the priviledged TCP/IP printer server port.
- X.PP
- The PLP distribution
- X.B test
- directory contains prototype or debugging versions of printcap,
- printer_perms,
- and other files;
- X.B test/Makefile
- will generate and install the necessary directories,
- etc.,
- and
- will install the necessary filters.
- The test devices have their spool directories in /tmp,
- and should be trivial to install.
- Run the tests listed below
- to ensure that the various programs are working.
- Note that all the functionality of the PLP software can be checked out
- as an ordinary user,
- and you do NOT need to run as ROOT.
- X.PP
- In summary,
- to make the test verions,
- do the following.
- X.IP 1).
- Create a bin directory,
- copy the Makefile from src,
- edit the Makefile and set the various system dependencies.
- X.IP 2).
- Run
- X.L "make all" .
- At this point you will have all of your binaries in the bin
- directory,
- where you should leave them.
- Set up your shell $path or $PATH to use
- X$(PLP)/bin directory ahead of /usr/ucb,
- otherwise you will use the existing LPD programs.
- X.IP 3).
- Go to the
- X.L test
- directory,
- read the
- X.L test/README
- file,
- edit the
- X.L test/Makefile
- according to directions,
- and do
- X.L "make bin" .
- in the
- X.L test
- directory.
- This generates some executables and places them in the /tmp
- directory,
- as well as installing a test version of the printer permission file.
- X.IP 4).
- Now you should take a nap,
- play rogue,
- or whatever you do to relax.
- The next part is not fun.
- X.NH 3
- Test 1\- LPC, LPR, LPQ
- X.PP
- To run the first tests,
- change to the
- X.L test
- directory and do
- X.L "make test1" .
- This installs the printcap file of Figure 11.2 in /tmp/printcap:
- X.KF
- X.in +1i
- X.nf
- X.DT
- X.L
- X.SM
- X.vs -2
- X.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 8i
- X#
- X# TEST VERSION OF PRINTCAP FILE:
- X# Test 1: simple lpr functions
- X#
- test:\e
- X :fx=flpdnt:ex:\e
- X :pw#75:pl#66:rw:\e
- X :br#9600:fs#040:fc#011:\e
- X :ty=new 19200 even -tabs tandem:\e
- X :lp=output:\e
- X :if=/tmp/filter -delay30:\e
- X :of=/tmp/lpf -D5:\e
- X :sd=/tmp/test:
- X.vs +2
- X.sp .5v
- X.R
- X.LG
- X.in -1i
- X.ce
- XFigure 11.2 Test 1 Printcap File
- X.KE
- X.PP
- You should look at the code for the
- X.L filter
- and the
- X.L lpf
- programs which were created by the
- X.L "make bin" .
- The
- X.L filter
- program is a handy dandy debugging filter.
- The
- X.L lpf
- filter simply copies stdin to stdout,
- and suspends itself when it detects the stop string.
- The
- X.L lpf
- filter source is the skeleton for any new filters that are needed.
- X.PP
- You can test the functionality of the
- lpq,
- and lpr
- programs by using the illustrated commands.
- Sample output has been provided.
- X.nf
- X.vs -2
- X.DT
- X.SM
- X.L
- X.ta 12n +4n +4n +4n +4n +4n +4n +4n
- X%>lpq -D5 #should display queue (empty)
- lpq: pid=4233, LOG_DEBUG, First_printer: simple at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Get_Printer: First_printer 'simple' at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Get_printer: using Printer simple at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Readlockfile: lockfile 'lock' at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Readlockfile: lock, perms 0100644 at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Readlockfile: 'lock' pid 0 len 0 at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, Checklockfile: lock server 0 at Fri May 20 17:02:08 1988
- lpq: simple- pid=4233, LOG_DEBUG, printstatus: ST status at Fri May 20 17:02:08 1988
- Printer 'simple' (attila.cs.umn.edu):
- X work done at Wed May 18 09:38:59 1988
- X
- X%>lpr xx #place job in queue
- lpr: Warning- File 'xx' not printed: cannot access it
- lpr: Fatal error- nothing to print
- X
- X%>echo hi | lpr #place job in queue
- lpr: simple- Startserver: host 'attila.cs.umn.edu' server for 'simple'
- X not started - Connection refused at Fri May 20 17:08:51 1988
- X
- X%>lpq #should display queue one entry
- Printer 'simple' (attila.cs.umn.edu):
- Warning: no server present
- X Rank Owner Pr Job Host Files Size
- X 1st papowell Z 13 attila (stdin) 3
- X
- X%>lpc #play with lpc
- X>status
- Queue Jobs Queueing Printing
- simple 1 enabled enabled (no server)
- X
- X>disable simple
- simple: queueing disabled
- X>status
- Queue Jobs Queueing Printing
- simple 1 disabled enabled (no server)
- X>quit
- X.R
- X.LP
- X.NH 3
- Test 2\- LPD Functionality
- X.PP
- Use the commands:
- X.ti +.5i
- X.L "echo >/tmp/error"
- X.ti +.5i
- X.L "lpd -D5 -L /tmp/error; tail -f /tmp/error"
- X.br
- to create the error log file and to start up ldp.
- It is best to do this at one terminal,
- and then do the remaining tests at another terminal.
- Lucky windowing system users will,
- of course,
- simply open another window.
- You will be amused to watch the lpd spring into action,
- trying to create servers,
- etc.
- The
- X.L simple
- server will log into the
- X.L /tmp/simple/log
- file.
- X.PP
- You can remove /tmp/test/log,
- and see the interaction of the lpd daemon and the printer server
- little clearer.
- To kill the lpd daemon,
- do the following:
- X.DS
- X.DT
- X.L
- X.SM
- lpc lpd ##- prints the lpd daemon id
- kill <pid> # kill off the daemon
- rm /tmp/test/log # remove the log file
- echo >/tmp/error
- lpd -D5 -L /tmp/error
- tail -f /tmp/error
- X.R
- X.DE
- X.PP
- If you are curious,
- try starting multiple
- X.L "lpd"
- programs;
- when
- X.L lpd
- is started,
- it checks for a running daemon,
- print a message,
- and then exits.
- X.PP
- You can examine the conditions of the servers and other
- activites by using
- X.I lpq .
- Note that the lpq status report includes a chatty informational piece about
- the job progress.
- X.PP
- The OF filter has been carefully created to print out
- various pieces of information.
- You can see what this is if you look at /tmp/test/output,
- where the output is going.
- You will notice that the IF filter is a shell script,
- and will do a sleep for a while.
- You can now test out the various lpq,
- lpr,
- and lpc functions.
- X.NH 3
- Test 3 \- Remote Servers
- X.PP
- These tests check out the functionality of inter host spooling functions.
- They have been written so that they will use the local host intitially,
- but can be extended to the remote host.
- X.PP
- In the
- X.L test
- direcotory, do
- X.L "make test2"
- to install the second form of the printcap file.
- You will not have to kill the lpd to do this.
- Now try
- X.ti +.5i
- X.L "lpq -Premote"
- X.br
- and examine the output.
- The lpq program will print out the local queue,
- and then send a message to the remote host (which is the local host)
- using the INET protocol.
- This will check out the functionality of the network communication.
- You can play with lpr,
- lpc,
- etc. and check this out.
- Try the
- X.I remote
- functions of the
- X.I lpc
- program.
- X.PP
- If you have two hosts available,
- install the PLP software on both of them.
- XEdit the printcap files so that one of them has the local test,
- and the other the remote test entry.
- Don't forget to install and modify the printer_perms file so that the
- remote host can access the test spool queue.
- Try the communications out.
- X.NH 3
- Test 4 \- Multiple Servers
- X.PP
- This will demonstrate how to have multiple servers for a single spool
- queue.
- Install the printcap file by doing
- make test3.
- Use lpq to check the status of the spool queue.
- Now use lpr to send a slog (10 or more) jobs to the multi queue.
- You can use
- X.ti +.5i
- X.L "lpq +10 -a"
- X.br
- to monitor what happens.
- X.NH 3
- Test 5 \- Serial Line Control
- X.PP
- If you have a printer,
- attach it to a suitable serial line,
- and modify the test printcap entry so that it is set up
- for the printer.
- I have found that the following procedure works pretty good.
- X.PP
- Set the
- X.B sh
- X(suppress headers or banners)
- in the printcap entry,
- and remove the
- X.B of
- entry.
- Set up a new entry for if,
- X.B "if=/tmp/serial -d30"
- and edit the filter program to print out the stty settings.
- You can now run lpr to try and send things out to the printer.
- You will either have lots of problems or no problems in communicating
- with the printer.
- X.PP
- Watch out for parity;
- you may have to fool around with the printer parity settings.
- I strongly suggest a NO parity setting.
- Tandem flow control is another tricky area.
- You may have to open the printer RW using
- X.B rw
- to get tandem flow control.
- This has been a problem with several installations.
- X.NH 2
- Installing a Working Version
- X.PP
- Before you install a the PLP software,
- you should make a copy of the existing print spooler software.
- There is a set of programs in the
- X.L backup
- directory of the PLP distribution that have proven to be very useful.
- X.IP 1).
- XEdit the
- X.L bin/Makefile ,
- and disable the XPERIMENT flag.
- Do a
- X.L "make clean; make all"
- to regenerate the working version.
- X.IP 2).
- Create a printer permissions file.
- You can base this on the version in the
- X.L test
- directory.
- The version
- in Figure 12.3 is useful for initial installations,
- and can be found in
- X.L test/printer_perms.all .
- X.KF
- X.nf
- X.SM
- X.L
- X.vs -2
- X# Printer permissions data base
- X# host user printerqueue maxpriority maxpages currentpages
- X# * is a wildcard
- X#host user printer perms pr maxpages pages
- X* root * * * 0 0 #root on any system
- X* * * R G 0 0 #anybody can do remote
- X.vs +2
- X.LG
- X.R
- X.sp .5v
- X.ce
- XFigure 11.3 Sample Printer Permissions File
- X.KE
- X.IP 3).
- Do a
- X.L "make install"
- and check that permissions have been set correctly.
- X.IP 4).
- Using the same tests as outlined above,
- make sure that lpr,
- lpc,
- and lpq
- are functional.
- X.IP 5).
- Start lpd
- and check that files are unspooled and transferred correctly.
- When sending files to remote sites,
- both must be running PLP versions.
- X.NH 2
- Organization of Printcap Information
- X.PP
- If you are working in an environment with a large number of
- different sites and different printers,
- you may find the programs in the
- X.L printcap
- directory handy to manage printcap files.
- The organization and management is based on the following structure.
- X.PP
- XEach printer has a physical location name and a set of aliases.
- XFor our sample printer,
- X.L printer_loc ,
- There is a
- X.L printer_loc.local
- file which contains a printcap entry suitable for the host which has the device
- attached,
- a
- X.L printer_loc.remote
- file which contains a printcap entry suitable for a host
- which can communicate directly to the remote host,
- and a
- X.L printer_loc.forward
- file which contains a printcap entry suitable for a host
- which forwards jobs to either a local or remote host.
- XFor example,
- here are typical entries for the 3 files.
- These files are stored in the directory
- X.L printcap/devices .
- XFigure 12.4 is a sample of several of them.
- X.KF
- X.TS
- center box;
- lw(2.5) | lw(2.5i) .
- X.L
- X.SM
- dg1_lind23.local dg1_lind23.remote
- X_
- T{
- X.nf
- dg1_lind23.local|dg1:\e
- X :sd=/usr/spool/dg1_lind23:\e
- X :lp=/dev/tty09:sy=9600 -even -odd:
- T} T{
- X.nf
- dg1_lind23.local|dg1:\e
- X :sd=/usr/spool/dg1_lind23:\e
- X :rm=attila:rp=dg1_lind23:
- T}
- X.TE
- X.TS
- center box;
- lw(2.5i) .
- X.L
- X.SM
- dg1_lind23.forward
- X_
- T{
- X.nf
- dg1_lind23.local|dg1:\e
- X :sd=/usr/spool/dg1_lind23:\e
- X :rm=attila:rp=dg1_lind23:
- T}
- X.TE
- X.ce
- XFigure 11.4 Sample Printcap Files
- X.KE
- X.PP
- XEach host will have a file containing the names of the entries in
- the printcap file.
- The
- X.L genpc
- program will generate a printcap file from the named printer file
- by concatenating the printcap information and placing it in a
- X.L host.printcap
- file.
- This file can then be copied to the desired destination.
- X.NH 2
- Checking Out Exisitng Printcaps and Filters
- X.PP
- If you have an exisiting printcap file,
- you can check it out by using the XPERIMENTAL form
- of PLP before you commit to the actual form.
- X.IP 1). 3
- XFirst,
- copy the original
- X.L /etc/printcap
- file to
- X.L /tmp/printcap.<host> .
- X.IP 2). 3
- Modify the
- X.L /tmp/printcap.<host>
- file so that the
- X.L /usr/spool
- directories in it are modified to be
- X.L /tmp
- directories.
- X.IP 3). 3
- Compile the test version of the PLP software;
- there is an entry in the makefile,
- X.L "make test"
- which will do this in an efficient manner.
- X.IP 4). 3
- Set your
- X.L $path
- to use the test version,
- and run
- X.L "checkpc -f"
- to create the spool direcotories needed by the
- X.L /tmp/printcap.<host>
- version.
- X.IP 4). 3
- You can now run a parallel version of the PLP software,
- and check out the behaviour of devices and filters.
- END_OF_FILE
- if test 15498 -ne `wc -c <'doc/PLP/11.t'`; then
- echo shar: \"'doc/PLP/11.t'\" unpacked with wrong size!
- fi
- # end of 'doc/PLP/11.t'
- fi
- if test -f 'src/localprinter.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/localprinter.c'\"
- else
- echo shar: Extracting \"'src/localprinter.c'\" \(16055 characters\)
- sed "s/^X//" >'src/localprinter.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: localprinter.c
- X * local Printer queue job handler
- X ***************************************************************************
- X * Revision History: Created Wed Jan 13 15:34:42 CST 1988
- X * $Log: localprinter.c,v $
- X * Revision 3.1 88/06/18 09:34:24 papowell
- X * Version 3.0- Distributed Sat Jun 18 1988
- X *
- X * Revision 2.4 88/05/21 10:27:48 papowell
- X * Minor editing
- X *
- X * Revision 2.3 88/05/19 10:33:53 papowell
- X * Fixed open() calls to have a 0 parameter, ie: open(f, perms, 0), where needed
- X *
- X * Revision 2.2 88/05/14 10:17:51 papowell
- X * Use long format for job file names;
- X * Added 'fd', no forward flag;
- X * Control file has to have hostname and origination agree.
- X *
- X * Revision 2.1 88/05/09 10:08:26 papowell
- X * PLP: Released Version
- X *
- X * Revision 1.5 88/05/09 10:03:18 papowell
- X * Revised effects of -h option
- X *
- X * Revision 1.4 88/05/05 20:08:11 papowell
- X * Added a NOHEADER option that allows user to suppress banner
- X *
- X * Revision 1.3 88/03/25 14:59:44 papowell
- X * Debugged Version:
- X * 1. Added the PLP control file first transfer
- X * 2. Checks for MX during file transfers
- X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
- X * apparently they open files and then assume that they will stay
- X * open.
- X * 4. Made sure that stdin, stdout, stderr was available at all times.
- X *
- X * Revision 1.2 88/03/05 15:01:02 papowell
- X * Minor Corrections, Lint Problems
- X *
- X * Revision 1.1 88/03/01 11:08:31 papowell
- X * Initial revision
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: localprinter.c,v 3.1 88/06/18 09:34:24 papowell Exp $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X
- X#include "lp.h"
- X
- char *Setup_filter(); /* setup filter */
- static int prjobs; /* numbers of jobs done */
- X
- X/**********************************************************************
- X * Printinit()
- X * 1. set up the state to indicated 0 completed jobs
- X * 2. get the printer ready
- X **********************************************************************/
- Printinit()
- X{
- X int n;
- X
- X if(Debug>3)log(XLOG_DEBUG,"Printinit: called with prjobs %d", prjobs );
- X n = Print_ready();
- X return( n );
- X}
- X
- X/**********************************************************************
- X * Printerror()
- X * called when there is an error in the job handling
- X * 1. set up the state to indicated 0 completed jobs
- X * 2. close the printer
- X **********************************************************************/
- void
- Printerror()
- X{
- X if(Debug>3)log(XLOG_DEBUG,"Printerror: called with prjobs %d", prjobs );
- X
- X prjobs = 0;
- X Print_close();
- X}
- X/**********************************************************************
- X * Printfinal()
- X * called when there is an error in the job handling
- X * 1. if there are completed jobs, print the trailer
- X * 2. close the printer
- X **********************************************************************/
- void
- Printfinal()
- X{
- X if(Debug>3)log(XLOG_DEBUG,"Printfinal: called with prjobs %d", prjobs );
- X /*
- X * print out trailer on close with a job out
- X */
- X if( prjobs ){
- X /*
- X * FQ set means FF needed on open
- X */
- X if( FQ && FF && *FF ){
- X if(Debug>3)log( XLOG_DEBUG, "Printfinal: FF on final");
- X (void)Print_string( FF );
- X }
- X if( TR && *TR ){
- X /*
- X * TR is sent out
- X */
- X if(Debug>2)log( XLOG_DEBUG, "Printfinal: TR '%s'", TR);
- X (void)Print_string( TR );
- X }
- X }
- X prjobs = 0;
- X Print_close();
- X}
- X
- X/**********************************************************************
- X * Printjob
- X * 1. First scan extracts information which controls printing
- X * 2. Set any default values not passed
- X * 3. Second scan does the printing.
- X * Returns: JBUSY, JFAIL, JSUCC, JABORT
- X * Side effects: sets information vector CFparm[].
- X **********************************************************************/
- Printjob(cfp, q)
- X FILE *cfp; /* control file */
- X struct queue *q; /* job entry */
- X{
- X int i; /* ACME Integer, Inc. */
- X char parm[BUFSIZ]; /* holds a line read in */
- X char *arg; /* control line argument */
- X char opt; /* control line option */
- X int jstatus; /* job status */
- X int perms = 'R'; /* file perms */
- X long jobsize; /* job size */
- X
- X if( fseek( cfp, 0L, 0 ) < 0 ){
- X logerr_die(XLOG_INFO, "Printjob: start- fseek failed" );
- X }
- X /*
- X * set job status
- X */
- X jstatus = JABORT; /* default */
- X /*
- X * initialize the CFparm array, which holds value read from file
- X */
- X for( i = 0; i < 26; ++i ){
- X CFparm[i][0] = 0;
- X }
- X
- X /*
- X * read the control file and extract user information
- X */
- X jobsize = 0;
- X while(fgets( parm, sizeof(parm), cfp )){
- X if( (arg = index(parm, '\n')) == 0 ){
- X log(XLOG_INFO,"Printjob: bad control file (%s), no endline",
- X q->q_name);
- X goto error;
- X }
- X *arg = 0;
- X opt = parm[0];
- X arg = parm+1;
- X if( !isascii(opt) || ! isalnum( opt )){
- X log( XLOG_INFO, "Printjob: bad control file (%s), line('%d'%s)",
- X q->q_name,opt, arg);
- X goto error;
- X }
- X /*
- X * copy it into the appropriate place if needed
- X */
- X if( isupper( opt ) ){
- X switch( opt ){
- X case 'U':
- X case 'N': break;
- X default:
- X if( CFparm[opt - 'A'][0] ){
- X log(XLOG_INFO,
- X "Printjob: duplicate %c parm '%s', previous:'%s'",
- X opt, arg, CFparm[opt-'A']);
- X goto error;
- X }
- X if( strlen( arg ) >= MAXPARMLEN ){
- X log(XLOG_INFO,
- X "Printjob: control file %s line too long:'%s'",
- X q->q_name,arg);
- X goto error;
- X }
- X (void)strcpy( CFparm[opt - 'A'], arg );
- X break;
- X }
- X } else if( islower( opt )){
- X if( Job_match( q->q_name, arg) == 0 ){
- X logerr(XLOG_INFO,"Printjob: bad control file '%s' entry '%s'",
- X q->q_name,parm);
- X goto error;
- X }
- X if( stat( arg, &LO_statb ) < 0 ){
- X logerr( XLOG_INFO,"Printjob: cannot stat file %s",arg);
- X goto error;
- X }
- X if( (i = Add_name( arg )) < 0 ){
- X logerr( XLOG_INFO,"Printjob: too many files %s",q->q_name);
- X goto error;
- X }
- X jobsize = jobsize + (LO_statb.st_size + 1023)/1024;
- X if( MX && jobsize > MX ){
- X logerr( XLOG_INFO,"Printjob: job too big %s",q->q_name);
- X goto error;
- X }
- X switch( opt ){
- X case 'f': /* uses the IF filter */
- X case 'l':
- X break;
- X default:
- X if( Filter_name[opt-'a'] == 0){
- X log( XLOG_INFO,"Printjob: no %c filter",opt);
- X goto error;
- X }
- X break;
- X }
- X }
- X }
- X /*
- X * Set up any parameters that were not provided to default values
- X */
- X if( PWIDTH[0] = 0){
- X (void)sprintf( PWIDTH, "%d", PW );
- X }
- X /*
- X * check permissions
- X */
- X if( strcmp( &q->q_from, FROMHOST ) ){
- X log(XLOG_INFO,
- X "Printjob: control file origin '%s' and H entry '%s' do not match",
- X &q->q_from, FROMHOST );
- X goto error;
- X }
- X if((Permfile && *Permfile &&
- X !Checkperm(Permfile,FROMHOST,LOGNAME,First_name,&perms,(int *)0,0))
- X ||(XU && *XU &&
- X !Checkperm(XU,FROMHOST,LOGNAME,First_name,&perms,(int *)0,0 ) )){
- X log(XLOG_INFO,
- X "Sorry %s@%s, you don't have permission to use '%s'",
- X LOGNAME, FROMHOST, First_name );
- X goto error;
- X } else if((Permfile && *Permfile &&
- X !Checkperm(Permfile,FROMHOST,LOGNAME,First_name,&perms,(int *)0,1))
- X ||(XU && *XU &&
- X !Checkperm(XU,FROMHOST,LOGNAME,First_name,&perms,(int *)0,1 ) )){
- X log( XLOG_INFO, "Sorry %s@%s, no more pages allowed on '%s'",
- X LOGNAME, FROMHOST, First_name );
- X goto error;
- X }
- X /*
- X * See if there are any files to print
- X */
- X if( Parmcount == 0 ){
- X /* no files */
- X if(Debug>4)log(XLOG_DEBUG,"Printjob: no files");
- X jstatus = JSUCC;
- X goto error;
- X }
- X /*
- X * Pass 2: Do the printing now
- X */
- X if( fseek(cfp, 0L, 0) < 0 ){
- X /* this is impossible */
- X logerr( XLOG_NOTICE, "Printjob: fseek %s failed",q->q_name);
- X goto error;
- X }
- X if( QH ){
- X /*
- X * queuejob returns one of the Job Status settings
- X */
- X jstatus = queuejob(cfp, q);
- X goto error;
- X }
- X /*
- X * Put out FF on open and between jobs
- X */
- X if( prjobs == 0 ){
- X /*
- X * FO set means FF needed on open
- X */
- X if( LD && *LD ){
- X if(Debug>3)log( XLOG_DEBUG, "Printjob: putting out LD on open");
- X jstatus = Print_string( LD );
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: LD on open printing failed" );
- X goto error;
- X }
- X }
- X if( FO && FF && *FF ){
- X if(Debug>3)log( XLOG_DEBUG, "Printjob: putting out FF on open");
- X jstatus = Print_string( FF );
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: FF on open printing failed" );
- X goto error;
- X }
- X }
- X prjobs = 1;
- X } else if( SF == 0 && FF && *FF ){
- X if(Debug>3)log(XLOG_DEBUG,"Printjob: putting out FF between jobs");
- X jstatus = Print_string( FF );
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: FF printing failed" );
- X goto error;
- X }
- X }
- X /*
- X * print banner
- X * if it has not been disabled by the SH flag
- X * or the lpr -h flag was used and the AB (always banner) is clear
- X */
- X if( !(SH || (NOHEADER[0] && !AB)) ){
- X jstatus = Print_banner();
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: banner printing failed" );
- X goto error;
- X }
- X prjobs = 1;
- X }
- X /*
- X * Banner Printing Program
- X */
- X if( BP && *BP ){
- X jstatus = Banner_print(BP);
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: BP program %s failed", BP);
- X goto error;
- X }
- X prjobs = 1;
- X }
- X /*
- X * print individual jobs
- X */
- X while(fgets( parm, sizeof(parm), cfp )){
- X if( (arg = index(parm, '\n')) == 0 ){
- X log( XLOG_INFO,"Printjob: bad control file format (%s), no endline",
- X q->q_name);
- X goto error;
- X }
- X *arg = 0;
- X opt = parm[0];
- X arg = parm+1;
- X if( opt == 0 || ! isalnum( opt )){
- X log( XLOG_INFO, "bad control file (%s), line(%s)",
- X q->q_name,parm);
- X goto error;
- X }
- X if( islower( opt ) ){
- X /*
- X * print the file
- X */
- X prjobs = 1;
- X jstatus = printfile( opt, arg );
- X if( jstatus != JSUCC ){
- X goto error;
- X }
- X }
- X }
- X /*
- X * End Printing Program
- X */
- X if( EP && *EP ){
- X jstatus = Banner_print(EP);
- X if( jstatus != JSUCC ){
- X log( XLOG_INFO, "Printjob: EP program %s failed", EP);
- X goto error;
- X }
- X prjobs = 1;
- X }
- X
- X /*
- X * error and status reporting
- X */
- error:
- X if( MAILNAME[0] ){
- X sendmail(q, jstatus);
- X }
- X if(Debug>3)log(XLOG_DEBUG,"Printjob: '%s' status %d",q->q_name,jstatus);
- X return (jstatus);
- X}
- X
- X/***********************************************************************
- X * printfile( int format; char *datafile )
- X * 1. determine the format and corresponding filter command
- X * 2. if 'p' format, set up pr process to format output
- X * 3. output to Printer
- X * Returns: JFAIL if retry, JSUCC if success, JABORT if ugly
- X ***********************************************************************/
- static int
- printfile(format, file)
- X int format;
- X char *file;
- X{
- X int dfd; /* data file fd */
- X int status; /* return status */
- X char *filter; /* program Name */
- X int nofilter = 0; /* no filter, just copy */
- X char buf[BUFSIZ]; /* hold the Printer command */
- X int p[2]; /* pipe file descriptors */
- X int prchild; /* Printer process */
- X
- X if(Debug>3)log( XLOG_DEBUG, "printfile: format %c, file %s", format, file);
- X /*
- X * Open input file
- X */
- X if ((dfd = open_daemon(file, O_RDONLY, 0)) < 0) {
- X logerr( XLOG_NOTICE,"printfile: open failed '%s'", file);
- X return(JABORT);
- X }
- X /*
- X * find filter chain to be generated
- X */
- X switch (format) {
- X /*
- X * use the filter Name tagged by 'Xf', where X is format
- X */
- X default:
- X filter = Setup_filter( format, Filter_name[format-'a']);
- X break;
- X /*
- X * 'f' and 'l' formats use the IF filter, and OF if not present
- X */
- X case 'f': /* default */
- X case 'l': /* ignore control */
- X case 'p': /* print file using 'pr' */
- X if( IF == 0 || *IF == 0){
- X /*
- X * you have to use the OF filter; we don't set up a filter
- X */
- X nofilter = 1;
- X } else {
- X filter = Setup_filter( 'f', IF);
- X }
- X if( format != 'p' ){
- X break;
- X }
- X /*
- X * create a process to invoke 'pr'
- X * first, set up the pr command
- X */
- X (void)sprintf(buf, "%s -w%d -l%d %s %s",
- X PR, PWIDTH, PL, PRTITLE[0]?"-h":"", PRTITLE);
- X if(Debug>3)log( XLOG_DEBUG, "printfile: pr command '%s'", buf);
- X /*
- X * create PR process
- X */
- X if( pipe(p) < 0 ){
- X logerr_die( XLOG_NOTICE, "printfile: cannot make pipe" );
- X }
- X /*
- X * make a pipe, fork PR process
- X * Run this process as DAEMON
- X */
- X if ((prchild = fork()) == 0) { /* child */
- X if( dup2(dfd, 0) < 0 /* file is stdin */
- X || dup2(p[1], 1) < 0 ){ /* pipe stdout */
- X logerr_die( XLOG_NOTICE, "printfile: dup2 failed, PR process" );
- X }
- X /* set the uid to be safe */
- X if( geteuid() == 0 && setreuid( Daemon_uid, Daemon_uid ) < 0 ){
- X logerr_die( XLOG_INFO, "printfile: setreuid failed" );
- X }
- X mexecv(buf);
- X logerr_die( XLOG_NOTICE,"printfile: cannot execv %s", buf);
- X } else if (prchild < 0) {
- X logerr_die( XLOG_NOTICE,"printfile: fork for pr failed");
- X }
- X (void) close(p[1]); /* close output side */
- X (void) close(dfd);
- X dfd = p[0]; /* use pipe for input */
- X break;
- X }
- X /*
- X * start filter
- X */
- X if( nofilter ){
- X status = Print_copy( dfd );
- X } else if (filter == 0 || *filter==0) {
- X log( XLOG_INFO,"printfile: no %c filter, file %s", format,file);
- X status = JABORT;
- X } else {
- X /*
- X * start filter up
- X */
- X if(Debug>0)log( XLOG_DEBUG,
- X "printfile: format %c, file %s, filter %s", format,file,filter);
- X status = Print_filter( dfd, filter );
- X }
- X (void)close( dfd );
- X return( status );
- X}
- X
- X/********************************************************************
- X * Banner_print( char *prog)
- X * Print the banner using the user specified program
- X * 1. setup the filter
- X * 2. start program
- X * 3. wait for completion.
- X ********************************************************************/
- Banner_print( prog )
- X char *prog;
- X{
- X char *filter;
- X int status;
- X
- X if(Debug>3)log( XLOG_DEBUG, "Banner_print %s", prog);
- X filter = Setup_filter( 'f', prog);
- X if (filter == 0 || *filter==0) {
- X log( XLOG_INFO,"Banner_printer: bad program %s", prog );
- X status = JABORT;
- X } else {
- X /*
- X * start filter up
- X */
- X if(Debug>3)log( XLOG_DEBUG, "Banner_print: filter %s", filter);
- X status = Print_filter( 0, filter );
- X }
- X return( status );
- X}
- X/********************************************************************
- X * queuejob()
- X * Use the user specified Queue Handler.
- X * exec'd as `qh -PPrinter -B[nsl] control_file'.
- X * exit codes are used to indicate the different success:
- X * 0 - successful; 1 retry; anything else- abandon
- X * Returns: JSUCC, etc.
- X * NOTE: the queue handler is invoked with the control file as
- X * stdin and the Printer as stdout.
- X ********************************************************************/
- X
- queuejob(cfp, q)
- X FILE *cfp; /* control file */
- X struct queue *q; /* queue entry */
- X{
- X union wait status;
- X int id, pid, ret;
- X char buf[BUFSIZ];
- X
- X /*
- X * set up arguments
- X */
- X (void)sprintf(buf, "%s %s", QH, Printer, q->q_name);
- X if(Debug>0)log( XLOG_DEBUG,"queuejob: %s", buf);
- X /*
- X * Open the Printer
- X */
- X Print_open();
- X if( (pid = fork()) == 0 ){ /* child */
- X if( dup2(fileno(cfp), 0) < 0 ){ /* stdin is cf */
- X logerr_die( XLOG_NOTICE, "queuejob: dup2 failed" );
- X }
- X if( dup2(Print_fd, 1) < 0 ){ /* stdin is cf */
- X logerr_die( XLOG_NOTICE, "queuejob: dup2 failed" );
- X }
- X if( geteuid() == 0 && setreuid( Daemon_uid, Daemon_uid ) < 0 ){
- X logerr_die( XLOG_INFO, "queuejob: setreuid failed" );
- X }
- X mexecv(buf);
- X logerr_die( XLOG_INFO, "queuejob: exec failed" );
- X } else if( pid < 0 ){
- X logerr_die( XLOG_INFO, "queuejob: fork failed" );
- X }
- X /*
- X * wait for process
- X */
- X if(Debug>0)log( XLOG_DEBUG, "waiting for queuejob %d", pid );
- X while ((id = wait(&status) ) > 0 && pid!=id){
- X if(Debug>3)log(XLOG_DEBUG,"queuejob: caught %d, %s", id,
- X Decode_status(&status) );
- X }
- X if(Debug>0)log( XLOG_DEBUG, "queuejob: pid %d status %s", id,
- X Decode_status(&status ) );
- X if( id < 0 || status.w_stopval != 0 || (unsigned)status.w_retcode > 1 ){
- X logerr( XLOG_INFO, "queuejob process %d failed, status (%s)",
- X id, Decode_status(&status));
- X ret = JABORT;
- X } else if( status.w_retcode == 1 ){
- X ret = JFAIL;
- X } else {
- X ret = JSUCC;
- X }
- X return (ret);
- X}
- END_OF_FILE
- if test 16055 -ne `wc -c <'src/localprinter.c'`; then
- echo shar: \"'src/localprinter.c'\" unpacked with wrong size!
- fi
- # end of 'src/localprinter.c'
- fi
- if test -f 'src/lpr_parms.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/lpr_parms.c'\"
- else
- echo shar: Extracting \"'src/lpr_parms.c'\" \(15634 characters\)
- sed "s/^X//" >'src/lpr_parms.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: lpr_parms.c
- X * get the parameters for lpr program
- X ***************************************************************************
- X * Revision History: Created Mon Jan 25 17:29:45 CST 1988
- X * $Log: lpr_parms.c,v $
- X * Revision 3.1 88/06/18 09:35:00 papowell
- X * Version 3.0- Distributed Sat Jun 18 1988
- X *
- X * Revision 2.4 88/05/25 15:42:37 papowell
- X * No header flag modification
- X *
- X * Revision 2.3 88/05/19 09:00:18 papowell
- X * Fixed lint unused variables
- X *
- X * Revision 2.2 88/05/14 10:18:40 papowell
- X * Use long format for job file names;
- X * Added 'fd', no forward flag;
- X * Control file has to have hostname and origination agree.
- X *
- X * Revision 2.1 88/05/09 10:09:23 papowell
- X * PLP: Released Version
- X *
- X * Revision 1.8 88/05/09 10:03:47 papowell
- X * Revised effects of -h option
- X *
- X * Revision 1.7 88/05/05 20:08:45 papowell
- X * Added a NOHEADER option that allows user to suppress banner
- X *
- X * Revision 1.6 88/04/07 12:31:53 papowell
- X * Modified to use Getopt
- X *
- X * Revision 1.5 88/04/06 12:13:46 papowell
- X * Minor updates, changes in error message formats.
- X * Elimination of the AF_UNIX connections, use AF_INET only.
- X * Better error messages.
- X *
- X * Revision 1.4 88/03/25 15:00:39 papowell
- X * Debugged Version:
- X * 1. Added the PLP control file first transfer
- X * 2. Checks for MX during file transfers
- X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
- X * apparently they open files and then assume that they will stay
- X * open.
- X * 4. Made sure that stdin, stdout, stderr was available at all times.
- X *
- X * Revision 1.3 88/03/11 19:28:41 papowell
- X * Minor Changes, Updates
- X *
- X * Revision 1.2 88/03/05 15:01:51 papowell
- X * Minor Corrections, Lint Problems
- X *
- X * Revision 1.1 88/03/01 11:08:50 papowell
- X * Initial revision
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: lpr_parms.c,v 3.1 88/06/18 09:35:00 papowell Exp $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X
- X#include "lpr.h"
- X
- X/***************************************************************************
- X * Setup_parms( int argc; char **argv )
- X * 1. get the parameters;
- X * 2. set up the get the printcap entry
- X * 3. check to see if any parameters violate the printcap restrictions
- X * 4. get the sequence number
- X ***************************************************************************/
- X
- Setup_parms( argc, argv )
- X int argc;
- X char **argv;
- X{
- X /*
- X * get the parameters
- X */
- X Get_parms( argc, argv );
- X /*
- X * print the parameters passed
- X */
- X if(Debug>4)Show_parms();
- X /*
- X * get the printcap entry
- X */
- X Get_Printer(1);
- X /*
- X * check authorizations
- X */
- X Can_use();
- X /*
- X * check consistency of parameters
- X */
- X Check_parms();
- X /*
- X * get the sequence number
- X */
- X Get_sequence();
- X if(Debug>4)Show_parms();
- X}
- X
- X/***************************************************************************
- X * Get_parms( int argc; char **argv )
- X * 1. Scan the argument list and get the flags
- X ***************************************************************************/
- X
- static char *optstr = "#:C:D:F:J:P:R:T:U:XZ:bcdfghi:lm?nprstvw:";
- Get_parms( argc, argv )
- X int argc;
- X char **argv;
- X{
- X int option;
- X int i;
- X
- X while( (option = Getopt(argc,argv,optstr)) != EOF ){
- X switch( option ){
- X case '#':
- X Check_int_dup( option, &Copies, Optarg );
- X break;
- X case 'C':
- X Check_str_dup( option, CLASSNAME, Optarg );
- X break;
- X case 'D':
- X Check_int_dup( option, &Debug, Optarg );
- X break;
- X case 'F':
- X if( strlen( Optarg ) != 1 ){
- X Diemsg( "bad -F format string '%s'\n",Optarg);
- X }
- X if( Format ){
- X Diemsg( "duplicate format specification -F%s\n", Optarg);
- X } else {
- X Format = *Optarg;
- X }
- X break;
- X case 'J':
- X Check_str_dup( option, JOBNAME, Optarg );
- X break;
- X case 'P':
- X if( Printer ){
- X Check_str_dup( option, Printer, Optarg );
- X }
- X if( *Optarg == 0 ){
- X Diemsg( "missing printer name in -P option\n" );
- X }
- X Printer = Optarg;
- X break;
- X case 'R':
- X Check_str_dup( option, ACCNTNAME, Optarg );
- X break;
- X case 'T':
- X Check_str_dup( option, PRTITLE, Optarg );
- X break;
- X case 'U':
- X Root_only( option );
- X Check_str_dup( option, BNRNAME, Optarg );
- X (void)strcpy( LOGNAME, Optarg );
- X break;
- X case 'X':
- X Check_dup( option, &Exper );
- X# ifdef DEBUG
- X Setup_test();
- X Tailor_names();
- X# else
- X Diemsg( "-X not allowed" );
- X# endif DEBUG
- X break;
- X case 'Z':
- X Check_str_dup( option, CLASSNAME, Optarg );
- X break;
- X case 'b':
- X Check_dup( option, &Binary );
- X break;
- X case 'h':
- X Check_dup( option, &Noheader );
- X /*
- X * set the NOHEADER flag for lpd
- X */
- X NOHEADER[0] = 'X';
- X break;
- X case 'i':
- X Check_str_dup( option, INDENT, Optarg );
- X break;
- X case 'm':
- X /*
- X * -m[Mailname]
- X */
- X if( Optarg == 0 ){
- X Check_str_dup( option, MAILNAME, Person );
- X (void)sprintf(MAILNAME,"%s@%s",Person,Host);
- X } else {
- X Check_str_dup( option, MAILNAME, Optarg );
- X }
- X break;
- X case 'r':
- X Check_dup( option, &Remove );
- X break;
- X case 's':
- X Check_dup( option, &Use_links );
- X break;
- X case 'c':
- X case 'd':
- X case 'f':
- X case 'g':
- X case 'l':
- X case 'n':
- X case 'p':
- X case 't':
- X case 'v':
- X if( Format ){
- X Diemsg( "duplicate format specification -%c\n", option);
- X exit( 1 );
- X } else {
- X Format = option;
- X }
- X break;
- X case '?':
- X break;
- X case 'w':
- X Check_str_dup( option, PWIDTH, Optarg );
- X i = atoi( PWIDTH );
- X if( i <= 0 ){
- X Diemsg( "-w <width>, width value '%s' bad", PWIDTH );
- X exit( 1 );
- X }
- X (void)sprintf( PWIDTH, "%d", i );
- X break;
- X default:
- X fatal(XLOG_INFO, "Get_parms: badparm %c", option );
- X }
- X }
- X
- X /*
- X * set up the Parms[] array
- X */
- X for( ; Optind < argc; ++Optind ){
- X if( Parmcount < MAXPARMS ){
- X Parms[Parmcount].str = argv[Optind];
- X ++Parmcount;
- X } else {
- X Diemsg( "too many files to print; break job up" );
- X }
- X }
- X /*
- X * set default format
- X */
- X if( Format == 0 ){
- X Format = 'f';
- X }
- X if( FROMHOST[0] == 0 ){
- X (void)strcpy(FROMHOST, Host);
- X }
- X}
- X
- X/***************************************************************************
- X * Check_int_dup( int option, int *value, char *arg )
- X * 1. check to see if value has been set
- X * 2. if not, then get integer value from arg
- X ***************************************************************************/
- X
- Check_int_dup( option, value, arg )
- X int option;
- X int *value;
- X char *arg;
- X{
- X if( *value ){
- X Diemsg( "duplicate option %c", option );
- X }
- X if( sscanf( arg, "%d", value ) != 1 || *value <= 0){
- X Diemsg( "option %c parameter (%s) is not positive integer",
- X option, arg);
- X }
- X}
- X/***************************************************************************
- X * Check_str_dup( int option, char *value, char *arg )
- X * 1. check to see if value has been set
- X * 2. if not, then set it
- X ***************************************************************************/
- Check_str_dup( option, value, arg )
- X int option;
- X char *value;
- X char *arg;
- X{
- X if( *value ){
- X Diemsg( "duplicate option %c", option );
- X }
- X if( strlen( arg ) > MAXPARMLEN ){
- X Diemsg( "option %c arguement too long (%s)", option, arg );
- X }
- X (void)strcpy(value, arg );
- X}
- X/***************************************************************************
- X * Check_dup( int option, int *value )
- X * 1. check to see if value has been set
- X * 2. if not, then set it
- X ***************************************************************************/
- Check_dup( option, value )
- X int option;
- X int *value;
- X{
- X if( *value ){
- X Diemsg( "duplicate option %c", option );
- X }
- X *value = 1;
- X}
- X/***************************************************************************
- X * Root_only( int option );
- X * 1. check to see if root
- X ***************************************************************************/
- Root_only( option )
- X int option;
- X{
- X if( Is_root == 0 ){
- X Diemsg( "option %c can be used only by root", option );
- X }
- X}
- X/***************************************************************************
- X * Can_use()
- X * Check for permissions and priority
- X * 1. RG - restrict access by group: must be in group
- X * 2. printcap: check for restrictions
- X * 3. XU: check for restrictions
- X ***************************************************************************/
- Can_use()
- X{
- X int prior; /* find the max priority */
- X int op; /* 'R' for lpr */
- X char buf[BUFSIZ];
- X char *pf; /* XU perm file */
- X
- X /*
- X * get the full path name
- X */
- X pf = XU;
- X if( pf && *pf && pf[0] != '/' ){
- X (void)sprintf( buf, "%s/%s", SD, pf );
- X pf = buf;
- X }
- X /*
- X * check for priority
- X */
- X Priority = CLASSNAME[0];
- X if( Priority == 0 ){
- X Priority = 'Z';
- X }
- X if( !isascii(Priority) || !isupper(Priority) ){
- X Priority = 'Z';
- X Warnmsg( "Priority set to %c", Priority );
- X }
- X /*
- X * check to see if we have access restricted by group perms
- X */
- X if( !Is_root && RG && *RG && !Checkgrp( Person,RG ) ){
- X Diemsg( "Sorry %s@%s, you don't have permission to use the %s",
- X Person, Host, Printer );
- X }
- X /*
- X * check to see if we have restricted access
- X */
- X prior = Priority;
- X op = 'R'; /* able to use lpr */
- X if((Permfile && *Permfile
- X && !Checkperm(Permfile,Host,Person,First_name,&op,(int *)0,0))
- X ||(pf && *pf
- X && !Checkperm(pf,Host,Person,First_name,&op,(int *)0,0 ) )){
- X Diemsg( "Sorry %s@%s, you don't have permission to use '%s'",
- X Person, Host, Printer );
- X }
- X if((Permfile && *Permfile
- X && !Checkperm(Permfile,Host,Person,First_name,&op,&prior,1 ))
- X ||(pf && *pf
- X && !Checkperm(pf,Host,Person,First_name,&op,&prior,1 ) )){
- X Diemsg( "Sorry %s@%s, no more pages allowed on '%s'",
- X Person, Host, Printer );
- X }
- X /*
- X * now check to see if you have not exceeded your page limits
- X */
- X if( prior > Priority ){
- X Warnmsg( "maximum Priority allowed is %c", prior );
- X Priority = prior;
- X }
- X if(Debug>2)log(XLOG_DEBUG,"Can_use: %s can use %s, priority %c",
- X Person, Printer, Priority );
- X}
- X
- X/***************************************************************************
- X * Checkgrp( name, list )
- X * -- check to see if person is a member of one of the groups
- X * Returns: 1 if person is a member, 0 if not
- X ***************************************************************************/
- X
- Checkgrp( name, list )
- X char *name, *list;
- X{
- X char buf[BUFSIZ];
- X char *cp, *bp;
- X struct group *gr;
- X char **grplist;
- X
- X if(Debug>4)log(XLOG_DEBUG,"Checkgrp: checking for %s in %s", name, list );
- X cp = list;
- X while( cp && *cp ){
- X for( bp = buf; *cp && (*bp = *cp) && (*bp != ','); ++bp, ++cp );
- X *bp = 0;
- X if( *cp ){
- X ++cp;
- X }
- X if(Debug>5)log(XLOG_DEBUG,"Checkgrp: checking group %s", buf );
- X if( gr = getgrnam(buf) ){
- X for( grplist = gr->gr_mem; *grplist; ++grplist ){
- X if( strcmp( name, *grplist ) == 0 ){
- X if(Debug>4)log(XLOG_DEBUG,"Checkgrp: %s in %s",
- X name, gr->gr_name );
- X return(1);
- X }
- X }
- X }
- X }
- X if(Debug>4)log(XLOG_DEBUG,"Checkgrp: %s not in any group" );
- X return( 0 );
- X}
- X/***************************************************************************
- X * Check_parms()
- X * Check for parameter consistency
- X * 1. Check to see if the format is allowed
- X * 2. Check on the multiple copies
- X ***************************************************************************/
- Check_parms()
- X{
- X char *msg;
- X /* check format and options */
- X if( FX && *FX && index( FX, Format ) == 0 ){
- X msg=NULL;
- X switch(Format){
- X case 'f': msg = "Normal or plain files"; break;
- X case 't': msg = "Troff files, use -Fn for Ditroff"; break;
- X case 'n': msg = "Ditroff files, use -Ft for (old) troff files";break;
- X case 'v': msg = "Varian raster images"; break;
- X case 'd': msg = "TeX intermediate files (DVI)"; break;
- X case 'g': msg = "Plot intermediate files"; break;
- X case 'c': msg = "Cifplot intermediate files"; break;
- X default: msg = "format 'X' files"; msg[8]=Format;
- X }
- X Diemsg("Printer %s does not know how to interpret %s\n", Printer, msg);
- X }
- X if( SC && Copies > 1){
- X Warnmsg("multiple copies are not allowed");
- X Copies = 0;
- X }
- X if(MC > 0 && Copies > MC){
- X Warnmsg("only %d copies are allowed", MC);
- X Copies = MC;
- X }
- X if( Remove && !Is_root
- X && (LN == 0 || *LN == 0 || !Checkgrp( Person, LN ))){
- X Warnmsg( "-r (remove) not allowed" );
- X Remove = 0;
- X }
- X#ifdef NOSYMLINK
- X if( Use_links ){
- X Warnmsg("-s (symbolic links) disabled");
- X Use_links = 0;
- X }
- X#else
- X if( Use_links ){
- X /*
- X * check to see if we are a member of the right group
- X */
- X if( !Is_root && (LN == 0 || *LN == 0 || !Checkgrp( Person, LN ) )){
- X Warnmsg("-s (symbolic links) not allowed by user %s", Person);
- X Use_links = 0;
- X } else if( RM && NW ){
- X Warnmsg("-s (symbolic links) not available for this queue" );
- X Use_links = 0;
- X }
- X }
- X#endif NOSYMLINK
- X if( Remove && !Use_links ){
- X Warnmsg( "-r (remove) not allowed without -s" );
- X Remove = 0;
- X }
- X}
- X
- X/***************************************************************************
- X * Get_sequence()
- X * Get the job sequence number
- X * 1. Check to see if queuing is enabled
- X * 2. Get the job number from the .job file
- X ***************************************************************************/
- X
- Get_sequence()
- X{
- X char buf[MAXPATHLEN]; /* holds the pathname */
- X FILE *fp; /* for sequence number */
- X int i; /* waiting time */
- X
- X /*
- X * check to see if printing is enabled
- X */
- X if( LO == 0 || *LO == 0 || SD == 0 || *SD == 0 ){
- X fatal( XLOG_CRIT, "Get_sequence: bad printcap entry" );
- X }
- X if( LO[0] == '/' ){
- X (void)strcpy( buf, LO );
- X } else {
- X (void)sprintf( buf, "%s/%s", SD, LO );
- X }
- X /*
- X * get the sequence file name
- X */
- X (void)sprintf( buf, "%s/.seq.%s", SD, Host );
- X if(Debug>3)log(XLOG_DEBUG,"sequence file name '%s'", buf );
- X /*
- X * lock the sequence file and get a new number
- X */
- X for( i = 0;
- X (fp = Getlockfile( buf, &Job_number,(char *)0,0,&LO_statb )) == NULL
- X && i < 3;
- X ++i ){
- X sleep( (unsigned)(i+ (getpid()&1) ) );
- X }
- X if( fp == NULL ){
- X Diemsg("cannot lock sequence file %s, try later (%s)", buf,
- X Errormsg( errno ) );
- X }
- X if( !Is_root && (LO_statb.st_mode & DISABLE_QUEUE) ){
- X Diemsg( "printer %s- queueing disabled", Printer );
- X }
- X /*
- X * set the sequence number to the new value mod 1000;
- X */
- X Job_number = (Job_number+1) % 1000;
- X Setlockfile( buf, fp, Job_number, Time_str() );
- X (void)fclose(fp);
- X if(Debug>4)log(XLOG_DEBUG, "Get_sequence: number %d", Job_number);
- X}
- X
- X/***************************************************************************
- X * Show_parms()
- X * Display the values of the parameters that were read.
- X * 1. Print the CFparm array
- X * 2. Print the other parameters
- X ***************************************************************************/
- X
- Show_parms()
- X{
- X int i;
- X char *s;
- X
- X /*
- X * CFparm first:
- X */
- X (void)fprintf(stderr,"CFparm:\n");
- X for( i = 'A'; i <= 'Z'; ++i ){
- X s = CFparm[i-'A'];
- X if( s[0] ){
- X (void)fprintf(stderr," %c '%s'\n", i, s );
- X }
- X }
- X (void)fprintf(stderr, " Format: %c\n", Format );
- X (void)fprintf(stderr, " Copies: %d\n", Copies );
- X (void)fprintf(stderr, " Binary: %d\n", Binary );
- X (void)fprintf(stderr, " Use_links: %d\n", Use_links );
- X (void)fprintf(stderr, " Exper: %d\n", Exper );
- X (void)fprintf(stderr, " Priority: %d\n", Priority );
- X (void)fprintf(stderr, " Job_number: %d\n", Job_number );
- X if( Read_stdin ){
- X (void)fprintf(stderr, " Read_stdin: %s\n", Read_stdin );
- X }
- X if( Filter_out ){
- X (void)fprintf(stderr, " Filter_out: %s\n", Filter_out );
- X }
- X (void)fprintf(stderr, " Temp_count: %d\n", Temp_count );
- X (void)fprintf(stderr, " Temp_max: %d\n", Temp_max );
- X for( i = 0; i < Temp_count; ++i ){
- X s = Temp_file[i];
- X (void)fprintf(stderr," %d '%s'\n", i, s );
- X }
- X}
- END_OF_FILE
- if test 15634 -ne `wc -c <'src/lpr_parms.c'`; then
- echo shar: \"'src/lpr_parms.c'\" unpacked with wrong size!
- fi
- # end of 'src/lpr_parms.c'
- fi
- echo shar: End of archive 11 \(of 16\).
- cp /dev/null ark11isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 16 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-