home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i018: Public lineprinter spooler package, Part05/16
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: papowell@julius.cs.umn.edu
- Posting-number: Volume 16, Issue 18
- Archive-name: plp/part05
-
- #! /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 5 (of 16)."
- # Contents: doc/PLP/05.t doc/PLP/09.t filters/lpf.c man/lpd.8
- # man/lpr.1 src/mexecv.c src/rmjob.c
- # Wrapped by papowell@attila on Wed Aug 10 10:44:53 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/PLP/05.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/PLP/05.t'\"
- else
- echo shar: Extracting \"'doc/PLP/05.t'\" \(7584 characters\)
- sed "s/^X//" >'doc/PLP/05.t' <<'END_OF_FILE'
- X.ig
- X$Header: 05.t,v 1.1 88/05/21 18:39:40 papowell Locked $
- X$log$
- X..
- X.bp
- X.NH 1
- Remote Spool Queue
- X.PP
- XEntries in a remote spool queue are transfered to the remote host
- by a server process forked by the
- X.I lpd
- daemon.
- The server process checks the spool queue for entries
- and then initiates communication with the remote host and the
- line printer daemon on the remote end.
- The following section discusses the protocol used to transfer files
- to the remote hosts.
- X.NH 2
- XEstablishing Communication
- X.PP
- Interhost job transfer is done by using the Internet (Inet)
- interprocess communication facilities.
- XFor an excellent tutorial on this,
- see the 4.3BSD Advanced Tutorial On Interprocess Communications.
- The client or process that wishes to send files to a remote host
- establishes communication using the following procedure.
- X.IP 1). 3
- The client opens an AF_INET socket,
- using the SOCK_STREAM protocol.
- The socket will use a reliable message delivery method for
- communication.
- Note that the socket is written to send a message,
- read to receive a message.
- X.IP 2). 3
- The client socket is bound to a reserved port on the local host,
- that is,
- a port on the local host whose port number is less than 1024.
- These are reserved ports and can only be bound to by
- root processes or a process which
- is SUID root.
- The server on the remote machine will check to ensure that the
- client originated his request from a reserved port.
- X.IP 3). 3
- The client determines the remote host addressing information using the
- X.IR gethostbynam (3)
- facility.
- This returns the network address of the remote host.
- X.IP 4). 3
- The client determines the port number that the remote
- X.I lpd
- server is listening on by using the
- X.IR getservent (3)
- facility;
- for example,
- X.L getservent("printer","tcp")
- will return the port number and other needed information.
- X.IP 5). 3
- Using the above information,
- the client process will use
- X.IR connect (2)
- to establish a connection to the remote host.
- If the connect call fails,
- then the client may retry a couple of times until successful,
- or terminate with an error condition.
- X.NH 2
- Sending Requests
- X.PP
- After establishing connection with the remote host,
- the
- X.I lpd
- daemon will fork a server process to deal with the request.
- The format of the requests is specified in
- Table 1.1.
- Requests consist of a simple message consisting of a flag
- X(unsigned character value) followed by a string terminated with a
- new line character.
- XFor example,
- the request to transfer files to the remote host consists of a line of the
- form:
- X.ti +5n
- X\&^Bprinter
- X.PP
- The remote server process uses network supplied information to
- determine the name of the client host machine,
- and the port that originated the message.
- It will check the local
- printer permissions file to determine if the host is allowed to access
- the specified printer spool queue.
- After checking this basic permission,
- the remote host will then perform any requested actions.
- X.NH 2
- XFile Transfers
- X.PP
- A job is transferred between the local and remote hosts by using one
- of two methods.
- The first method is to send the data files of a job first,
- followed by the control file (Berkeley Protocol);
- the second method is to send the control file,
- followed by the data files (PLP Protocol).
- The
- X.B fj
- flag is used to select the PLP (control file first) protocol to be used
- in sending jobs.
- The default protocol is the Berkeley (data files first) protocol.
- X.PP
- The file transfer protocol consists of sending a line identifying
- the type of protocol being used,
- the size of the file (in bytes),
- and the name of the file.
- The remote host will return a single
- X0 (zero)
- confirmation byte if it agrees to accept the file;
- any other value is a fatal error.
- After confirmation,
- the file is transferred to the other end,
- followed by a single
- X0 (zero) byte.
- If the remote end receives the file and the terminating 0 byte,
- it will return a confirming
- X0 (zero) byte.
- The next file may then be transferred.
- After all files have been transferred,
- a single
- X0 (zero) byte will terminate the file transfer.
- X.PP
- The file transferred to the remote site will be placed in the
- remote site spool queue directory,
- with the same path name it had at the local site.
- Both the local and remote sites will lock any files being
- transfered in order to prevent other PLP processes from
- manipulating them.
- Table 5.1 specifies the values of the flags used in the protocol.
- X.KF
- X.TS
- tab(:) box center;
- l | l | l.
- Protocol:Flag:Meaning
- X_
- Berkeley:2 (^B):control file
- Both:3 (^C):data file
- PLP:4 (^D):control file
- PLP:5 (^E):last file
- X.TE
- X.ce
- Table 5.1. File Transfer Protocol Flags
- X.KE
- X.PP
- To use the Berkeley Protocol,
- the data files would be transferred first using the 3 (^B) flag,
- followed by the control file using the 2 (^C) flag.
- To use the PLP Protocol,
- the control file would be transferred first
- using the 4 (^D) flag,
- followed by the data files.
- When all of the data files had been transferred,
- a confirming message would be sent using the 5 (^E) flag,
- indicating that the job had been transferred.
- X.PP
- XFor example,
- assume that we have a job with a control file
- X.L cfA123attila.cs.umn.edu ,
- and a data file
- X.L dfA123attila.cs.umn.edu .
- Using the Berkeley Protocol,
- the client would first send the message
- X.ti +5n
- X.L "^C1293 dfA123attila.cs.umn.edu" ,
- X.br
- requesting transfer of a 1293 byte data file,
- whose name is
- X.L dfA123attila .
- After confirmation,
- the data file followed by a single 0 byte would be sent,
- and a confirmation should be received.
- Next,
- the message
- X.L "^B343 cfA123attila.cs.umn.edu" ,
- would be sent,
- and then the control file followed by a single 0 byte would be sent.
- Having received the control file,
- the remote end would acknowledge the reception of the job,
- allowing the client to delete the job and send another one.
- When control file is transferred,
- the remote host will check the job to make sure that all data files have
- been transferred,
- and enable it for printing or further processing.
- If anything happens to disturb this communication,
- the connection is terminated and any partially transferred jobs are
- removed.
- X.PP
- To prevent interaction between an unspooler server and a file
- transfer server,
- the job control file is locked by the file transfer server until it
- has been completely transferred.
- X.NH 2
- XError Recovery and Retry
- X.PP
- When either end of the file transfer protocol detects an error,
- they will shut down the link.
- It is the responsibility of the client process to retry sending jobs.
- X.NH 2
- Security Checks and Authorizations
- X.PP
- The PLP file transfer protocol restricts the names of control and
- data files to a fixed format.
- In addition,
- the
- X.B U
- X(unlink) flag has no effect on a remote host.
- The enforcement of the fixed format of data and control file names
- makes it simple to remove all files associated with a job on
- completion.
- X.PP
- Before placing a job in the spool queue,
- the user name and hostname are checked to see if permissions are
- acceptible.
- The security of this check is based on the assumption that the client
- host is a trusted originator of PLP jobs.
- In a networked environment with many different users,
- this may not be the case,
- as it is possible to forge information in a control file.
- The
- X.B fd
- X(no forward)
- flag in a printcap entry prevents the acceptance of jobs from other than
- the current client.
- This is intended to prevent clients from attempting to transfer control
- files that would appear to have originated from another
- host.
- While this will provide verification at the host level,
- assuming that network level software will uniquely identify a host,
- it still does not provide a secure user identification.
- END_OF_FILE
- if test 7584 -ne `wc -c <'doc/PLP/05.t'`; then
- echo shar: \"'doc/PLP/05.t'\" unpacked with wrong size!
- fi
- # end of 'doc/PLP/05.t'
- fi
- if test -f 'doc/PLP/09.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/PLP/09.t'\"
- else
- echo shar: Extracting \"'doc/PLP/09.t'\" \(6569 characters\)
- sed "s/^X//" >'doc/PLP/09.t' <<'END_OF_FILE'
- X.ig
- X$Header: 09.t,v 1.1 88/05/21 18:39:48 papowell Locked $
- X$log$
- X..
- X.NH 1
- Line Printer Spooler Administration
- X.PP
- Most of the administration of PLP commands consists of
- printcap entries,
- permissions entries,
- and spooler queue management.
- In addition,
- killing and restarting the
- X.I lpd
- daemon is sometimes needed.
- X.NH 2
- Printcap File Management
- X.PP
- XEach spool queue or printer must have an entry in a printcap file.
- In a single,
- non-networked environment,
- this is usually a simple and easily managed system,
- but in a highly networked environment it may be a difficult procedure.
- In order to simply the generation of printcap files,
- the PLP distribution has a set of programs that allow a simple printcap
- data base to be set up,
- and a set of programs to generate printcaps for different hosts.
- X.NH 3
- Printer Names
- X.PP
- Printer names and aliases are a major problem faced by administrators.
- The convention adopted by many sites is to make the primary (first)
- name of the printer correspond to the physical printer type and its
- location.
- XFor exmple,
- X.L lw_lind23
- is the name of the Apple LaserWriter in Lind Hall 23.
- Additional aliases or names can then be added.
- X.PP
- In performing permissions checking,
- the name supplied by the user is checked against the information in the
- printer permissions file,
- and also checked in the printcap database.
- XFor this reason,
- the name used in the printer permissions file and the
- name of the printer should be identical.
- When sending files to a remote site,
- the printer name found in the printcap entry and not the
- alias provided by a user is used to determine permissions.
- X.NH 3
- Printcap File Generation
- X.PP
- XEach printer usually has three forms of printcap entries:
- remote,
- forward,
- and actual device.
- The remote entry is used by a system that will treat the spool queue
- as a remote site and forward all jobs to a remote site.
- The forwarding entry is usually used for sites that accept jobs
- from other sites,
- and then forward them to a remote site.
- The forwarding is usually done by a specialized file transfer program.
- XFinally,
- a local or actual device entry is used for the host which has the
- actual printer attached.
- XFiles with the appropriate form printcap entry can be prepared.
- As part of the PLP software,
- a set of programs to generate printcap files tailored to a
- particular host has been developed,
- and is available in the
- X.L printcap
- directory.
- X.NH 3
- Printer Permissions File
- X.PP
- The main printer permissions file is intended to act as a filter for
- general user permissions.
- As described elsewhere,
- each line is checked for a matching set of user permissions,
- and the first matching line determines the available permissions.
- It is strongly suggested that the set of entries in the printcap
- file be used to filter out unauthorized users,
- and the remaining set of entries used to determine the appropriate
- permissions.
- X.PP
- If restrictions on the number of pages are desired,
- the printer permissions file can be used on a global or local basis.
- The current page count field is compared against the maximum
- field at the time a job is spooled or printed.
- In order to keep this file concurrent,
- some form of simple permissions file updating must be done.
- This can be done by using the
- X.I pac
- X(printer accounting) program and a suitable shell script.
- Due to the wide divergence of different sites,
- an accounting package to do this automatically has not been
- provided.
- X.NH 2
- Using LPC
- X.PP
- The
- X.I lpc
- program provides control over line printer activity.
- The major commands and their intended use are described in this section.
- See
- X.IR lpc (8)
- for details.
- X.LP
- X.B
- status and lpq
- X.R
- X.IP
- Status is used to display the current status of various line printers.
- The lpq function invokes lpq with various parameters.
- This is useful to monitor various printer activities.
- X.LP
- X.B
- start, abort, kill
- X.R
- X.IP
- X.I Start
- enables printing and requests
- X.I lpd
- to start printing jobs.
- X.sp
- X.I Abort
- disables unspooling and terminates an active server and its
- filters.
- This is normally used to kill a
- catatonic filter or spooler process
- X(i.e.,
- X.I lpq
- reports that there is a daemon present but nothing is
- happening).
- It does not remove any jobs from the queue.
- X.sp
- X.I Kill
- does an abort followed by a start.
- This is handy to kill a server and start another.
- Note that there is an upper limit on the numbers of times a server will
- attempt to print a job.
- X.B
- enable and disable
- X.R
- X.IP
- X.I Enable
- and
- X.I disable
- control spooling to a queue.
- This is used to prevent
- X.I lpr
- from putting new jobs in the spool queue.
- The main use is to prevent users from putting jobs in the queue
- when the printer is expected to be unavailable for a long time.
- X.LP
- X.B restart
- X.IP
- X.I Restart
- allows mere mortals users to restart printer daemons when
- X.I lpq
- reports that there is no daemon present.
- X.LP
- X.B stop
- X.IP
- X.I Stop
- disables unspooling,
- but does not kill off the server.
- This is a clean way to shutdown a printer in order to perform
- maintenence, etc.
- Note that users can still enter jobs in a
- spool queue while a printer is
- X.IR stopped .
- X.LP
- X.B topq
- X.IP
- X.I Topq
- places jobs at the top of a printer queue.
- This can be used to reorder high priority jobs.
- X.LP
- X.B
- remote (command)
- X.R
- X.IP
- X.I remote
- is used to send a command to the remote site for processing.
- This is useful to control remote line printer queues.
- X.LP
- X.B clean
- X.IP
- X.I clean
- totally purges a queue.
- This functionality is needed very infrequently,
- and perhaps should be removed.
- X.NH 2
- Starting the LPD Daemon
- X.PP
- Under various circumstances it may be necessary to kill and/or
- restart the
- X.I lpd
- daemon.
- The currently executing daemon writes
- its process ID and the time it was started in the
- X.L /usr/spool/lock.lpd
- file.
- The
- program in Figure 9.1,
- usually stored in
- X.L /usr/etc/lpd.kill ,
- can be used to kill and restart the LPD daemon.
- X.KF
- X.in +1i
- X.SM
- X.L
- X.nf
- X.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 8i
- X#!/bin/csh -f
- set p=`head -1 /usr/spool/lpd.lock`
- set h=`hostname`
- if ( "$p" == "" ) then
- X echo $h - no lpd daemon
- else
- X echo $h - daemon $p
- X kill $p
- X sleep 1
- X /usr/lib/lpd
- endif
- X.fi
- X.LG
- X.R
- X.in -1i
- X.ce
- XFigure 9.1 lpd.kill Program
- X.KE
- X.PP
- In a heavily networked system,
- it may be desirable to kill and restart daemons on a set of machines.
- The
- program in Figure 9.2,
- usually stored in
- X.L /usr/etc/lpd.all ,
- can be used to kill and restart remote daemons.
- X.KF
- X.in +1i
- X.SM
- X.L
- X.nf
- X.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 8i
- X#!/bin/csh -f
- set l=(`cat /etc/remote.lpd`)
- foreach i ($l)
- X rsh $i /usr/etc/lpd.kill
- X echo done $i
- endfor
- X.LG
- X.R
- X.in -1i
- X.ce
- XFigure 9.2 lpd.all Program
- X.KE
- END_OF_FILE
- if test 6569 -ne `wc -c <'doc/PLP/09.t'`; then
- echo shar: \"'doc/PLP/09.t'\" unpacked with wrong size!
- fi
- # end of 'doc/PLP/09.t'
- fi
- if test -f 'filters/lpf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'filters/lpf.c'\"
- else
- echo shar: Extracting \"'filters/lpf.c'\" \(6527 characters\)
- sed "s/^X//" >'filters/lpf.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: lpf.c
- X ***************************************************************************
- X * Revision History: Created Fri Mar 4 19:05:43 CST 1988
- X * $Log: lpf.c,v $
- X * Revision 2.2 88/05/19 07:35:38 papowell
- X * fixed minor bug with overstrikes
- X *
- X * Revision 2.1 88/05/09 10:12:08 papowell
- X * *** empty log message ***
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: lpf.c,v 2.2 88/05/19 07:35:38 papowell Locked $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X/***************************************************************************
- X * LPF and VPF filters.
- X * Filter which converts lines with ^H's to overwritten lines.
- X * Thus this works like 'ul' but is much better; it can handle
- X * more than 2 overwrites and it is written with some style.
- X *
- X * Also used as the versatec driver, with the VERSATEC defined
- X * Original source for this was the 4.2BSD release, but there have
- X * been substantial modifications since. This version has been derived
- X * from a total rewrite done in 1985.
- X ***************************************************************************/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X
- extern int errorcode;
- X/* set from flags */
- extern int debug, width, length, xwidth, ylength, literal, indent;
- extern char *zopts, *class, *job, *login, *accntname, *host, *accntfile;
- extern char *printer, *format, *name;
- extern int npages; /* number of pages */
- extern char *calloc(); /* memory allocation */
- X
- X#ifdef VERSATEC
- X#include <sys/vcmd.h>
- X
- X
- int pltmode[] = {VPLOT};
- int prtmode[] = {VPRINT};
- X#define MAXREP 10
- X
- X#else VERSATEC
- X/* line printer */
- X
- X#define MAXREP 10
- X#endif VERSATEC
- X
- X#define TIMEOUT (5*60) /* 5 minute time out */
- X
- char *buf;
- int *maxcol;
- int lineno;
- X
- X
- int timeout();
- X
- filter(stop)
- X char *stop;
- X{
- X register FILE *p = stdin, *o = stdout;
- X register int i, j, col;
- X register char *cp;
- X int done, linedone, maxrep;
- X unsigned int bufsize;
- X char ch, *limit;
- X int state, partial;
- X
- X partial = 0;
- X state = 0;
- X if( xwidth <= 0 ){
- X xwidth = width;
- X /* fatal( "bad xwidth value %d", xwidth ); */
- X }
- X if( width > xwidth || width <= 0 ){
- X fatal( "width (%d) out of range, max %d", width, xwidth );
- X }
- X /*
- X * check on width
- X */
- X bufsize = (unsigned)( MAXREP * xwidth );
- X if( (buf = calloc( bufsize, sizeof(char) )) == 0
- X || (maxcol = (int *)calloc( (unsigned)( MAXREP ), sizeof(int) )) == 0 ){
- X fatal( "malloc failed");
- X }
- X maxcol[0] = -1;
- X state = 0;
- X /*
- X * set up timeout
- X */
- X
- X# ifdef VERSATEC
- X (void) signal( SIGALRM, timeout );
- X errorcode = 1; /* set retry on failure */
- X if( ioctl(1, VSETSTATE, prtmode) < 0 ){
- X logerr_die( "ioctl failed" );
- X }
- X# endif VERSATEC
- X
- X
- X for( i = 0; i < MAXREP; ++i ){
- X maxcol[i] = -1;
- X }
- X for( i = 0; i < bufsize; ++i ){
- X buf[i] = ' ';
- X }
- X done = 0;
- X
- X while (!done) {
- X col = indent;
- X maxrep = -1;
- X linedone = 0;
- X while (!linedone) {
- X if( state ){
- X /* we read a partial stop and want to process it normally */
- X ch = stop[partial];
- X ++partial;
- X if( partial == state ){
- X state = 0;
- X }
- X } else {
- X ch = getc(p);
- X if( stop && ch == *stop){
- X /* we have hit the first character in the stop sequence */
- X for(state = 1;
- X stop[state] && (ch = getc(p)) == stop[state];
- X ++state );
- X /* we either have last, or we have a bad character */
- X if( stop[state] == 0 ){
- X state = 0; /* suspend yourself!! */
- X /*
- X * if this filter is running as the OF
- X * filter, it is used only for banners.
- X * lpd needs to use a different filter to
- X * print data so stop what we are doing and
- X * wait for lpd to restart us.
- X */
- X (void)alarm( TIMEOUT );
- X if( fflush(stdout) < 0 ){
- X logerr_die( "fflush failed" );
- X }
- X (void)alarm( 0 );
- X suspend();
- X# ifdef VERSATEC
- X if( ioctl(1, VSETSTATE, prtmode) < 0 ){
- X logerr_die( "ioctl failed" );
- X }
- X# endif VERSATEC
- X } else {
- X /* we don't have all of the characters */
- X partial = 0;
- X if( ch != EOF ){
- X (void)ungetc(ch, stdin);
- X }
- X }
- X /* we want to iterate, using new characters */
- X continue;
- X }
- X }
- X switch (ch) {
- X case EOF:
- X linedone = done = 1;
- X ch = '\n';
- X break;
- X
- X case '\f':
- X lineno = length;
- X case '\n':
- X if (maxrep < 0)
- X maxrep = 0;
- X linedone = 1;
- X break;
- X
- X case '\b':
- X --col;
- X if( col < indent)
- X col = indent;
- X break;
- X
- X case '\r':
- X col = indent;
- X break;
- X
- X case '\t':
- X col = ((col - indent) | 07) + indent + 1;
- X break;
- X
- X default:
- X if (col >= width || !literal && !isprint(ch)) {
- X col++;
- X break;
- X }
- X if(debug)fprintf(stderr,"ch '%c', col %d\n", ch, col );
- X cp = buf+col;
- X for (i = 0; i < MAXREP; i++) {
- X if (i > maxrep)
- X maxrep = i;
- X if (*cp == ' ') {
- X *cp = ch;
- X if (col > maxcol[i])
- X maxcol[i] = col;
- X break;
- X }
- X cp += xwidth;
- X }
- X col++;
- X }
- X }
- X
- X /* print out lines */
- X (void)alarm( TIMEOUT );
- X /* print out the lines in order of last to first */
- X if(debug){
- X fprintf(stderr,"maxrep %d\n");
- X }
- X for (i = maxrep; i >= 0; --i) {
- X cp = buf+i*xwidth;
- X if(debug){
- X fprintf(stderr,"line %d, col %d, '%s'\n",i,
- X maxcol[i], cp);
- X }
- X if( (col = maxcol[i]+1) > 0 ){
- X if(col != fwrite(cp,1,col,o)){
- X logerr_die( "write failed" );
- X }
- X }
- X for( j = 0; j < xwidth; ++j ){
- X cp[j] = ' ';
- X }
- X maxcol[i] = -1;
- X# ifdef PRINTRONIX
- X if( putc('\r', o) < 0 ){
- X logerr_die( "putc failed" );
- X }
- X# else PRINTRONIX
- X if( i > 0 ){
- X if( putc('\r', o) < 0 ){
- X logerr_die( "putc failed" );
- X }
- X }
- X# endif PRINTRONIX
- X }
- X if( putc(ch, o) < 0 ){
- X logerr_die( "write failed" );
- X }
- X (void)alarm( 0 );
- X
- X /*
- X * update page count
- X */
- X if(++lineno >= length){
- X npages++;
- X lineno = 0;
- X }
- X }
- X
- X (void)alarm( TIMEOUT ); /* set up timeout */
- X if (lineno) { /* be sure to end on a page boundary */
- X if( putc('\f', o) < 0 ){
- X logerr_die( "putc failed" );
- X }
- X npages++;
- X }
- X (void)fflush( o );
- X if( ferror(o) ){
- X logerr_die( "write failed" );
- X }
- X (void)alarm( 0 );
- X }
- X
- X
- timeout()
- X {
- X fatal( "timeout" );
- X }
- X
- X/*
- X * do nothing on cleanup
- X */
- X
- cleanup()
- X {}
- END_OF_FILE
- if test 6527 -ne `wc -c <'filters/lpf.c'`; then
- echo shar: \"'filters/lpf.c'\" unpacked with wrong size!
- fi
- # end of 'filters/lpf.c'
- fi
- if test -f 'man/lpd.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/lpd.8'\"
- else
- echo shar: Extracting \"'man/lpd.8'\" \(6781 characters\)
- sed "s/^X//" >'man/lpd.8' <<'END_OF_FILE'
- X.TH LPD 8 "19 Mar 1988" "U-MN PLP"
- X.ig
- X$Header: lpd.8,v 2.1 88/05/09 10:08:31 papowell Exp $
- X$Log: lpd.8,v $
- Revision 2.1 88/05/09 10:08:31 papowell
- PLP: Released Version
- X
- Revision 1.1 88/04/28 10:58:50 papowell
- Initial revision
- X
- X..
- X.SH NAME
- lpd \- line printer daemon
- X.SH SYNOPSIS
- X.B /usr/lib/lpd
- X[\-Llogfile] [\-D[n]] [\-X]
- X.SH DESCRIPTION
- X.I Lpd
- is the line printer daemon (spool queue handler) and is normally invoked
- at boot time from the
- X.IR rc (8)
- file. It makes a single pass through the
- X.IR printcap (5)
- file to find out about the existing printers and
- starts spool queue servers.
- It then uses the system calls
- X.IR listen (2)
- and
- X.IR accept (2)
- to receive requests to print files in the queue,
- transfer files to the spooling area,
- display the queue,
- remove jobs from the queue,
- or perform a spool queue control function.
- In each case it creates a server process to handle
- the request and the lpd process will listen for more requests.
- The
- X.B \-L
- option specifies an alternate file to be used for logging error messages.
- The
- X.IR syslog (8)
- facility is used to log critical messages as well.
- The
- X.B \-D
- flag enables generation of debugging messages,
- and the
- X.B \-X
- flag forces use of an Xperimental version of the software if it
- is avilable.
- X.PP
- Access control is provided by two means:
- a general set of printer permissions determined by the
- X.I /etc/printer_perm
- file,
- and an optional additional set of restrictions set by the
- X.B XU
- X(check user) permissions file specified in the printcap entry.
- XEach entry in the /etc/printer_perm file specifies a machine,
- user,
- printer,
- and maximum priority allowed;
- the ``*'' is a wildcard entry and matches anything.
- XFor example,
- the following entry allows root on any machine,
- to have to access to all queues and any priority,
- all users to have access to the lp queue but only a max of
- C priority,
- and admin on central to have access to the pr queue.
- The max and current fields are used to determine the maximum
- and current number of pages used by a particular user;
- this information is checked by the particular device
- to determine if a user or group of users have exceeded their
- limits,
- and is usually present only in the device specific permissions file.
- X.RS
- X.nf
- X.ta 1.i +1.i +1.i +.5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
- X#host user queue priority max current
- X* root * A 0 0
- X* * lp C 0 0
- central admin lp C 0 0
- X.fi
- X.RE
- X.PP
- The spool queue
- X.I lock
- file in each spool directory is used to
- control spooling activities,
- prevent multiple servers from becoming active simultaneously,
- and to store information about the server process.
- The
- X.IR lpr (1),
- X.IR lpq (1),
- X.IR lpc (1)
- and
- X.IR lprm (1)
- programs use this file to report on queue status.
- To gain control of a spool queue,
- a server process locks the control file,
- and then unspools the jobs.
- XEach job has a control file and a set of data files.
- Lines in the control file
- file specify files to be printed or non-printing actions to be
- performed.
- XEach line consists of a flag character and a parameter.
- Lower case letters are reserved for the format
- indication,
- specified by the
- X\-F
- option of LPR.
- the following is a partial list of the flag characters and their uses.
- X.in +3
- X.IP J
- Job Name. String to be used for the job name on the burst page.
- X.IP C
- Classification.
- String to be used for the classification line
- on the burst page and to determine job priority.
- The first letter of the string sets the level;
- A is highest, Z is lowest.
- The maximum level that can be used is determined by the
- printer_perm database and/or the
- X.B XU
- printcap entry.
- X.IP L
- Literal.
- The line contains identification info from
- the password file and appears on the banner page.
- X.IP T
- Title. String to be used as the title for
- X.IR pr (1).
- X.IP H
- Host Name. Name of the machine where
- X.I lpr
- was invoked.
- X.IP P
- Person. Login name of the person who invoked
- X.IR lpr .
- This is used to verify ownership by
- X.IR lprm .
- X.IP M
- Send mail to the specified user when the current print job completes.
- X.IP Z
- zoptions. Options passed by
- X.IR lpr
- X.IR -Zzoptions.
- These are passed to output filters.
- X.IP f
- XFormatted File. Name of a file to print which is already formatted.
- X.IP l
- Like ``f'' but passes control characters and does not make page breaks.
- X.IP p
- Name of a file to print using
- X.IR pr (1)
- as a filter.
- X.IP t
- Troff File. The file contains
- X.IR troff (1)
- output (cat phototypesetter commands).
- X.IP d
- DVI File. The file contains
- X.IR Tex (l)
- output (DVI format from Stanford).
- X.IP g
- Graph File. The file contains data produced by
- X.IR plot (3X).
- X.IP c
- Cifplot File. The file contains data produced by
- X.IR cifplot .
- X.IP v
- The file contains a raster image.
- X.IP r
- The file contains text data with FORTRAN carriage control characters.
- X.IP 1
- Troff Font R. Name of the font file to use instead of the default.
- X(Obsolete, not used)
- X.IP 2
- Troff Font I. Name of the font file to use instead of the default.
- X(Obsolete, not used)
- X.IP 3
- Troff Font B. Name of the font file to use instead of the default.
- X(Obsolete, not used)
- X.IP 4
- Troff Font S. Name of the font file to use instead of the default.
- X(Obsolete, not used)
- X.IP W
- Width. Changes the page width (in characters) used by
- X.IR pr (1)
- and the text filters.
- X.IP I
- Indent. The number of characters to indent the output by (in ascii).
- X.IP U
- Unlink. Name of file to remove upon completion of printing.
- X.IP N
- XFile name. The name of the file which is being printed, or a blank
- for the standard input (when
- X.I lpr
- is invoked in a pipeline).
- X.in -5
- X.PP
- The spool server will attempt to print a job a limited number of times
- before abandoning it.
- X.PP
- X.I Lpd
- uses
- X.IR flock (2)
- to provide exclusive access to the lock file and to prevent multiple
- deamons from becoming active simultaneously. If the daemon should be killed
- or die unexpectedly, the lock file need not be removed.
- The lock file is kept in a readable ASCII form
- and contains two lines.
- The first is the process id of the daemon and the second is the control
- file name of the current job being printed. The second line is updated to
- reflect the current status of
- X.I lpd
- for the programs
- X.IR lpq (1)
- and
- X.IR lprm (1).
- X.SH FILES
- X.nf
- X.ta \w'/etc/printcap 'u
- X/etc/printcap printer description file
- X/usr/spool/* spool directories
- X/dev/lp* line printer devices
- X/dev/printer socket for local requests
- X/etc/hosts.equiv lists machine names allowed printer access
- X/etc/printer_perms permissions
- X.fi
- X.SH "SEE ALSO"
- lpc(8),
- pac(1),
- lpr(1),
- lpq(1),
- lprm(1),
- printcap(5)
- X.br
- X.I "PLP - The Public Line Printer Spooler",
- by
- Patrick Powell,
- University of Minnesota.
- X.fi
- X.SH "HISTORY"
- X.PP
- The PLP is a reverse engineered version of the Berkeley 4.3BSD Line Printer
- Spooler.
- It has many advanced features which are described in
- X.I "PLP - The Public Line Printer Spooler"
- by
- Patrick Powell,
- University of Minnesota.
- END_OF_FILE
- if test 6781 -ne `wc -c <'man/lpd.8'`; then
- echo shar: \"'man/lpd.8'\" unpacked with wrong size!
- fi
- # end of 'man/lpd.8'
- fi
- if test -f 'man/lpr.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/lpr.1'\"
- else
- echo shar: Extracting \"'man/lpr.1'\" \(7221 characters\)
- sed "s/^X//" >'man/lpr.1' <<'END_OF_FILE'
- X.TH LPR 1 "19 Mar 1988" "U-MN PLP"
- X.ig
- X$Header: lpr.1,v 2.2 88/05/19 07:43:00 papowell Locked $
- X$Log: lpr.1,v $
- Revision 2.2 88/05/19 07:43:00 papowell
- XFixed up the -H, -h descriptions
- X
- Revision 2.1 88/05/09 10:08:40 papowell
- PLP: Released Version
- X
- Revision 1.2 88/05/09 10:01:51 papowell
- added -h option
- X
- Revision 1.1 88/04/28 10:58:53 papowell
- Initial revision
- X
- X..
- X.SH NAME
- lpr \- off line print
- X.SH SYNOPSIS
- X.B lpr
- X[
- X.BI \-P printer
- X] [
- X.BI \-# num
- X] [
- X.B \-C
- X.I class
- X] [
- X.B \-J
- X.I job
- X] [
- X.BI \-R remoteAccount
- X] [
- X.BI \-m \fR[\fImailTo\fR]\fI
- X] [
- X.B \-T
- X.I title
- X]
- X[\fB\-i\fP[\fInumcols\fP]]
- X[
- X.BI \-w num
- X] [
- X.BI \-Z zoptions
- X] [
- X.BI \-U user
- X] [
- X.BI \-F filter
- X] [
- X.B \-bhrs
- X] [
- X.BI \-D n
- X] [
- X.B \-X
- X] [
- filename ...
- X]
- X.SH DESCRIPTION
- X.B Lpr
- uses a spooling daemon to print the named files when facilities
- become available. If no names appear, the standard input is assumed.
- X.IP "\fB\-P\fIprinter\fR" 5
- Output to the specific printer;
- the default is to use
- the value of the
- environment variable PRINTER and
- and then the default (site dependent) printer.
- X.IP "\fB\-F\fIf\fR" 5
- XFilter or format specification.
- By default,
- input is assumed to a standard text file and the
- X.I f
- format is used;
- the output device is assmed to be a simple line printer.
- Therer are other formats available,
- listed below.
- Not all formats may be available on all printers;
- see
- X.IR printcap (5)
- for details.
- XFormats are single lower case letters;
- the following are the valid arguments for
- X.B \-F
- together with the assumed type of data.
- XFor compatibility with previous versions of
- X.BR lpr ,
- the format types can be used as options themselves
- X(i.e. by omitting the
- X.BR F )
- except where noted below,
- a warning may be issued in such cases.
- X.IP \fBp\fP 5
- text to be printed using
- X.IR pr (1)
- to format the files.
- The output is then formatted using the
- X.I f
- format.
- X.IP \fBl\fP 5
- text with control characters to be printed,
- and page breaks suppressed.
- X.IP \fBt\fP 5
- output from
- X.IR troff (1)
- X(originally cat phototypesetter commands,
- but now we assume the same as the
- X.B n
- format).
- X.IP \fBn\fP 5
- output from (device independent)
- X.IR troff .
- X.IP \fBd\fP 5
- output from
- X.IR tex (l)
- X(DVI format from Stanford).
- X.IP \fBg\fP 5
- standard plot data as produced by the
- X.IR plot (3X)
- routines (see also
- X.IR plot (1G)
- for the filters used by the printer spooler).
- X.IP \fBv\fP 5
- a raster image for devices like the Benson Varian.
- X.IP \fBc\fP 5
- data produced by
- X.IR cifplot (l).
- X.IP \fBr\fP 5
- text in which the first character of each line is interpreted as a
- standard FORTRAN carriage control character.
- The effect of this format used to be obtained with the
- X.B \-f
- option.
- X.PP
- The remaining single letter options have the following meaning.
- X.IP \fB\-m\fP[\fImailTo\fP] 5
- Send mail upon completion to user
- X.I mailTo
- X(default is to the submitter).
- If the \-m flag is followed by another flag or a single \-,
- the default submitter name will be used.
- X.IP \fB\-h\fP 5
- Request no banner or header for this job.
- X.IP \fB\-s\fP 5
- Use symbolic links.
- Usually files are copied to the spool directory.
- This flag will cause a symbolic link to be made to the file,
- and the file should not be modified or removed until it has been printed.
- Primarily useful for printing very large files,
- and its use is restricted due to security loopholes.
- X.IP \fB\-r\fP 5
- Remove the file after printing it.
- This option is also restricted due to security loopholes.
- X.IP \fB\-J\fP\ \fIjobname\fP 5
- Specify the job name to print on the burst page;
- defaults to the name of the first file.
- X.IP \fB\-T\fP\ \fItitle\fP 5
- Specify the title used by
- X.IR pr (1);
- defaults to the file name.
- X.IP \fB\-w\fP\fIwidth\fP 5
- Specify the page width for
- X.IR pr .
- X.IP \fB\-C\fP\ \fIclass\fP 5
- Specify the job classification for use on the burst page and to
- set the priority.
- Priorities range from A (highest) to Z (lowest);
- the default priority is Z.
- XFor example,
- X.br
- X.ti +0.5i
- lpr \-C A foo.c
- X.br
- sets the priority to A and the file foo.c to be printed.
- X.IP \fB\-R\fP\ \fIremoteAccount\fP 5
- Specify accounting information to be used by a remote system that prints
- your output.
- X.sp
- XFor some printers,
- such as the Imagen,
- it can be used to specify a real money billing code to be charged for the
- printing. This is only needed if the user has more than one
- real money billing code.
- X.IP \fB\-#\fP\fInum\fP 5
- Specify the number of copies of each file to be printed.
- Note that this option is NOT SUPPORTED on all printers,
- and its use is strongly discouraged.
- X.IP \fB\-i\fP[\fInumcols\fP] 5
- Cause the output to be indented;
- X\fInumcols\fP defaults to 8 blanks.
- Note that this option is NOT SUPPORTED on all printers,
- and thus its use is discouraged.
- X.IP \fB\-b\fP 5
- The files are assumed to contain binary data. This option allows the
- X.I lpr-spooler
- to be used for file transfers.
- X.IP "\fB\-Z\fP\ \fIextra\ options\fP" 5
- This option is used to pass extra options to the input filter for the printer
- in question and is mainly used when spooling to non-Unix printers or when
- using the spooler to to do file transfers to non-Unix machines.
- X.IP "\fB\-D\fR[\fIn\fR]"
- XEnables display of debugging information.
- The
- X.B \-D
- selects level 1;
- X.B \-D\fIn\fR
- X\fRselects level
- X.I n
- X(n is a single digit).
- X.IP "\fB\-X"
- Use an Xperimental version of LPD if the software has been compiled
- with the appropriate support;
- ignored otherwise.
- X.PP
- The
- X.B \-U
- option is used to specify a user name
- for the purpose of accounting and banners.
- X.PP
- The old LPR options
- X.B \-1234
- are obsolete;
- they were used to specify a font to be mounted on font position \fIi\fR.
- The
- X.B \-r
- X(delete files on job completion)
- and
- X.B \-s
- options are restricted to users who are in a group specified by the
- X.B ln
- X(allowed to use links) printcap entry for the printer.
- X.SH FILES
- X.nf
- X.ta \w'/usr/spool/*/cf* 'u
- X/etc/passwd personal identification
- X/etc/printcap printer capabilities data base
- X/etc/printer_perms printer permissions
- X/usr/lib/lpd* line printer daemons
- X/usr/spool/* directories used for spooling
- X/usr/spool/*/cf* daemon control files
- X/usr/spool/*/df* data files specified in "cf" files
- X/usr/spool/*/tf* temporary copies of "cf" files
- X.fi
- X.SH DIAGNOSTICS
- The diagnostics from
- X.I lpr
- are extremely verbose.
- If you try to spool too large a file
- or too many files,
- the job will be rejected.
- If this is the case,
- use
- X.I cat
- to append the files and then pipe them to LPR.
- X.I Lpr
- will object to printing binary files,
- as determined by a crude sanity and a.out header check.
- If a connection to the
- X.I lpd
- daemon socket /dev/printer cannot be made,
- X.I lpr
- will say that the server cannot be started.
- X.PP
- XEntries in the printcap will determine the exact actions taken by
- X.I lpr
- in spooling files;
- see the
- X.IR printcap (5)
- man pages for details.
- X.IR lpd .
- X.SH "SEE ALSO"
- lpq(1),
- lprm(1),
- pr(1),
- printcap(5),
- lpc(8),
- lpd(8),
- X.br
- X.I "PLP - The Public Line Printer Spooler",
- by
- Patrick Powell,
- University of Minnesota.
- X.fi
- X.SH "HISTORY"
- X.PP
- The PLP is a reverse engineered version of the Berkeley 4.3BSD Line Printer
- Spooler,
- done in 1988 at the University of Minnesota.
- It has many advanced features which are described in
- X.I "PLP - The Public Line Printer Spooler"
- by
- Patrick Powell,
- Department of Computer Science,
- University of Minnesota.
- END_OF_FILE
- if test 7221 -ne `wc -c <'man/lpr.1'`; then
- echo shar: \"'man/lpr.1'\" unpacked with wrong size!
- fi
- # end of 'man/lpr.1'
- fi
- if test -f 'src/mexecv.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/mexecv.c'\"
- else
- echo shar: Extracting \"'src/mexecv.c'\" \(6769 characters\)
- sed "s/^X//" >'src/mexecv.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: mexecv.c
- X * ExecrV a la 4 BSD for brain damaged System V
- X ***************************************************************************
- X * Revision History: Created Sat Jan 9 15:23:23 CST 1988
- X * $Log: mexecv.c,v $
- X * Revision 3.1 88/06/18 09:35:11 papowell
- X * Version 3.0- Distributed Sat Jun 18 1988
- X *
- X * Revision 2.1 88/05/09 10:09:36 papowell
- X * PLP: Released Version
- X *
- X * Revision 1.6 88/04/28 11:02:48 papowell
- X * removed unused variables, shuts up lint
- X *
- X * Revision 1.5 88/04/27 20:24:08 papowell
- X * Modified the SYSV Braindamaged mode to invoke shells better.
- X * The invocation is rather odd, but appears to work.
- X *
- X * Revision 1.4 88/03/25 15:00:52 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:29:44 papowell
- X * Minor Changes, Updates
- X *
- X * Revision 1.2 88/03/05 15:00:56 papowell
- X * Minor Corrections, Lint Problems
- X *
- X * Revision 1.1 88/03/01 11:08:56 papowell
- X * Initial revision
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: mexecv.c,v 3.1 88/06/18 09:35:11 papowell Exp $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X
- X/***************************************************************************
- X * ExecrV a la 4 BSD for brain damaged System V
- X * Sun Dec 6 20:04:57 CST 1987 Patrick Powell
- X * This is a massive hack, based on all sorts of checks and balances.
- X *
- X * 1. First, we try blinding using exev()
- X * 2. Next, we check the perms; if not executable, tough.
- X * 3. Next we try to read the file; if not readable, tough.
- X * 4. We read the first character of the file.
- X * 5. If it is not #, use Bourne shell;
- X * 6. We check for the #!; if not, we use CSH
- X * 7. We get the pathname of the file, and args, and use that.
- X */
- X#include "lp.h"
- X
- mexecv( command)
- X char *command;
- X{
- X int i; /* ACME Integer, Inc. */
- X struct stat statb;
- X FILE *fp;
- X char buf[BUFSIZ];
- X char cmd[BUFSIZ];
- X char *cp;
- X char *args[100];
- X char **argv = args+2;
- X char *option = 0;
- X char *fname;
- X char *path;
- X
- X /*
- X * close all the file descriptors
- X */
- X for( i = 3; i < NOFILE; ++i){
- X (void)close(i);
- X }
- X /*
- X * split command line up
- X */
- X (void)strcpy(cmd,command);
- X if( getwords(cmd, argv, 98) == 0 ){
- X log(XLOG_INFO,"mexecv: invalid argv passed, command %s",command);
- X return;
- X }
- X if(Debug>4){
- X char **s, b[BUFSIZ];
- X (void)sprintf(b,"mexecv: ");
- X for( s = argv; *s; ++s){
- X (void)sprintf(b+strlen(b),"'%s' ",*s);
- X }
- X log(XLOG_DEBUG,"%s",b);
- X }
- X execv( argv[0],argv );
- X
- X if(Debug>4)logerr(XLOG_DEBUG,"mexecv: execv failed" );
- X
- X /*
- X * well, that didn't work, lets try the shell options
- X */
- X fname = argv[0];
- X if( stat(fname, &statb) < 0 ){
- X logerr( XLOG_INFO,"mexecv: cannot stat %s", fname );
- X return;
- X }
- X if(Debug>4)log(XLOG_DEBUG,
- X "mexecv: %s, perms %o, st_uid %d, st_gid %d, uid %d, gid %d",
- X fname,statb.st_mode &0777, statb.st_uid, statb.st_gid,
- X getegid(), geteuid());
- X if(! (statb.st_mode & 0001)
- X && !((statb.st_mode & 0010) && statb.st_gid == getegid())
- X && !((statb.st_mode & 0100) && statb.st_uid == geteuid())){
- X log( XLOG_INFO,"mexecv: %s has no valid execute perms",fname);
- X return;
- X }
- X fp = fopen( fname, "r" );
- X if( fp == NULL ){
- X logerr(XLOG_INFO,"mexecv: cannot open %s for reading and failed execv",
- X fname);
- X return;
- X }
- X if( fgets( buf, sizeof(buf), fp ) == NULL
- X || (cp = index(buf, '\n')) == NULL ){
- X /* empty file , bad format */
- X log( XLOG_INFO,"mexecv: bad format %s", fname );
- X return;
- X }
- X (void)fclose(fp);
- X *cp = 0;
- X if( buf[0] != '#' ){
- X path = "/bin/sh";
- X } else {
- X /* check for the #! magic number */
- X if( buf[1] != '!' ){
- X /* use csh, be paranoid, and sure */
- X path = "/bin/csh";
- X } else {
- X /* we have an explicit path Name formed */
- X for( path = &buf[2]; *path && isspace(*path); ++path);
- X /* path points to the start of the command */
- X if( *path == 0 ){
- X log( XLOG_INFO,"mexecv: bad format %s", path );
- X return;
- X }
- X /* look for the end of the command */
- X for( cp = path; *cp && !isspace(*cp); ++cp );
- X if( *cp ){
- X /* we have options */
- X *cp = 0;
- X for( ++cp; *cp && isspace(*cp); ++cp);
- X option = cp;
- X ++cp;
- X for( ++cp; *cp && !isspace(*cp); ++cp);
- X *cp = 0;
- X }
- X }
- X }
- X if( strcmp( path, "/bin/csh" ) == 0 ){
- X /* we are using csh */
- X if( option == 0 ){
- X option = "-f";
- X } else {
- X (void)strcat(option, "f");
- X }
- X } else if (strcmp( path, "/bin/sh") == 0 ){
- X /*
- X * nothing
- X */
- X ;
- X } else {
- X fatal( XLOG_INFO,"mexecv: shell (%s) not /bin/csh or /bin/sh", path );
- X }
- X if( option ){
- X --argv;
- X argv[0] = option;
- X }
- X --argv;
- X argv[0] = fname;
- X if(Debug>4){
- X char **s, b[BUFSIZ];
- X (void)sprintf(b,"mexecv: path '%s'", path);
- X for( s = argv; *s; ++s){
- X (void)sprintf(b+strlen(b),"'%s' ",*s);
- X }
- X log(XLOG_DEBUG,"%s",b);
- X }
- X execv( path,argv );
- X logerr_die(XLOG_INFO,"mexecv: execv failed '%s'", path);
- X}
- X
- X
- X/*
- X * getwords splits a string up into words, and returns a non-null
- X * pointer if there are any.
- X * Note that splitting is done on a crude basis of matched quotes only
- X */
- int
- getwords(s, argv, maxargc)
- X char *s; /* string containing isspace separated words */
- X char *argv[];
- X int maxargc;
- X{
- X char **w;
- X char *tp = s;
- X int num_words = 0;
- X
- X if (s==NULL || *s == 0 )
- X return(0);
- X while (*tp) {
- X while(*tp && isspace(*tp))
- X ++tp;
- X if (*tp == 0) continue;
- X num_words++;
- X if( *tp == '\'' ){
- X if( (tp = index( tp+1, '\'')) == 0 ){
- X log(XLOG_INFO,"getwords: unmatched ' in string: %s", s );
- X return(0);
- X }
- X ++tp;
- X } else if( *tp == '\"' ){
- X if( (tp = index( tp+1, '\"')) == 0 ){
- X log(XLOG_INFO,"getwords: unmatched ' in string: %s", s );
- X return(0);
- X }
- X ++tp;
- X } else {
- X while ((*tp) && !isspace(*tp))
- X ++tp;
- X }
- X }
- X if (num_words==0)
- X return(0);
- X if( num_words > maxargc ){
- X log(XLOG_INFO,"getwords: more than %d arguments" );
- X return(0);
- X }
- X w = argv;
- X while(*s) {
- X while(*s && isspace(*s))
- X ++s;
- X if (*s == 0) {
- X *w = NULL;
- X return(1);
- X }
- X if( *s == '\'' ){
- X *w++ = s+1;
- X s = index( s+1, '\'');
- X *s++ = 0;
- X } else if( *s == '\"' ){
- X *w++ = s+1;
- X s = index( s+1, '\"');
- X *s++ = 0;
- X } else {
- X *w++ = s;
- X while ((*s) && !isspace(*s))
- X ++s;
- X if( *s ) *s++ = '\0';
- X }
- X }
- X *w = NULL;
- X return(1);
- X}
- END_OF_FILE
- if test 6769 -ne `wc -c <'src/mexecv.c'`; then
- echo shar: \"'src/mexecv.c'\" unpacked with wrong size!
- fi
- # end of 'src/mexecv.c'
- fi
- if test -f 'src/rmjob.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rmjob.c'\"
- else
- echo shar: Extracting \"'src/rmjob.c'\" \(7416 characters\)
- sed "s/^X//" >'src/rmjob.c' <<'END_OF_FILE'
- X/***************************************************************************
- X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
- X ***************************************************************************
- X * MODULE: rmjob.c
- X * Remove jobs from a printer queue
- X ***************************************************************************
- X * Revision History: Created Sat Jan 9 20:08:26 CST 1988
- X * $Log: rmjob.c,v $
- X * Revision 3.1 88/06/18 09:35:34 papowell
- X * Version 3.0- Distributed Sat Jun 18 1988
- X *
- X * Revision 2.2 88/05/14 10:21:11 papowell
- X * Modified -X flag handling
- X *
- X * Revision 2.1 88/05/09 10:10:09 papowell
- X * PLP: Released Version
- X *
- X * Revision 1.4 88/03/25 15:01:32 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:29:16 papowell
- X * Minor Changes, Updates
- X *
- X * Revision 1.2 88/03/05 15:01:42 papowell
- X * Minor Corrections, Lint Problems
- X *
- X * Revision 1.1 88/03/01 11:09:11 papowell
- X * Initial revision
- X *
- X ***************************************************************************/
- X#ifndef lint
- static char id_str1[] =
- X "$Header: rmjob.c,v 3.1 88/06/18 09:35:34 papowell Exp $ PLP Copyright 1988 Patrick Powell";
- X#endif lint
- X
- X#include "lp.h"
- X
- X/***************************************************************************
- X * rmjob()
- X * 1. get the printcap entries
- X * 2. get the queue entries
- X * 3. get the active server files and see if they are in queue
- X * 4. scan the queue, checking each job for removal
- X *
- X * user local job from remove_all perms inlist remove?
- X * ===============================================================
- X * root yes * * yes * * yes
- X * root yes * * no * yes yes
- X * root no * mach yes * * yes
- X * root no * mach no * yes yes
- X * user - user mach - R yes yes
- X * user - * * - C yes yes
- X *
- X * 5. remove the job; this may necessitate stopping or killing a deamon
- X ***************************************************************************/
- static int remove_all; /* remove all jobs */
- static int control_perms; /* has C perms */
- X
- rmjob()
- X{
- X int i; /* ACME Integers, Inc. */
- X struct queue *q; /* job entry */
- X int perms; /* hold perms values */
- X
- X /*
- X * get the printcap entry
- X */
- X if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
- X (void)fprintf(stdout, "Printer %s does not exist\n", Printer );
- X (void)fflush(stdout);
- X return;
- X }
- X if( SD == 0 || *SD == 0 ){
- X if(Debug>2)log(XLOG_DEBUG,"not a Printer");
- X return;
- X }
- X /* chdir to spool directory */
- X if (chdir(SD) < 0) {
- X logerr_die( XLOG_NOTICE,"cannot chdir to %s", SD);
- X }
- X /*
- X * set the flags needed
- X */
- X Is_local = strcmp( From, Host ) == 0;
- X Is_root = strcmp( Person, "root" );
- X remove_all = (Parmcount > 0 && (strcmp( Parms[0].str, "-all" ) == 0));
- X /*
- X * check to see that the user has RMJOB privs on this machine
- X */
- X perms = 'R'; /* must be able to at least use the Printer */
- X if( !Is_root && (
- X (Permfile && *Permfile
- X && !Checkperm( Permfile,From,Person,First_name,&perms,(int *)0,0 ))
- X || (XU && *XU
- X && !Checkperm( XU,From,Person,First_name,&perms,(int *)0,0 )))) {
- X (void)fprintf(stdout, "No remove permission on %s", First_name);
- X return;
- X }
- X perms = 'C'; /* check for control perms */
- X control_perms = 0;
- X if( !Is_root && (
- X (Permfile && *Permfile
- X && Checkperm( Permfile,From,Person,First_name,&perms,(int *)0,0 ))
- X || (XU && *XU
- X && Checkperm( XU,From,Person,First_name,&perms,(int *)0,0 )))) {
- X control_perms = 1;
- X }
- X if(Debug>4)log(XLOG_DEBUG,
- X "rmjob: Is_root %d, Is_local %d, remove_all %d, control_perms %d",
- X Is_root, Is_local, remove_all, control_perms );
- X /*
- X * check for remote machine and networked file system
- X */
- X if( RM && NW ){
- X Remote_remove();
- X return;
- X }
- X /*
- X * get the job queue
- X */
- X Jobcount = Getq();
- X (void)Checkactive();
- X /*
- X * run down list
- X */
- X (void)fprintf(stdout,"Printer '%s' (%s):\n", Printer, Host );
- X (void)fflush(stdout);
- X for( i = 0; i < Jobcount; ++i ){
- X q = &Queue[i];
- X if( shouldremove( q ) ){
- X (void)fprintf(stdout,"removing %s, job %d owner %s\n",
- X q->q_name, q->q_num, q->q_user);
- X (void)fflush(stdout);
- X doremove(q);
- X }
- X }
- X /*
- X * check for remote machine
- X */
- X if( RM ){
- X Remote_remove();
- X }
- X /*
- X * give the server a kick
- X */
- X (void)Startserver();
- X}
- X
- X/***********************************************************************
- X * shouldremove( q )
- X * a simple application of the removal decision table
- X *
- X * user local job from remove_all perms inlist remove?
- X * ===============================================================
- X * root yes * * yes * * yes
- X * root yes * * no * yes yes
- X * root no * mach yes * * yes
- X * root no * mach no * yes yes
- X * user - user mach - R yes yes
- X * user - * * - C yes yes
- X *
- X * Returns: 1 if removal is indicated, 0 otherwise
- X ***********************************************************************/
- int
- shouldremove( q )
- X struct queue *q;
- X{
- X int i, same_host;
- X
- X same_host = (strcmp( From, &q->q_from ) == 0);
- X i = Match_entry(q);
- X if( Is_root && Is_local && remove_all ) return(1);
- X if( Is_root && Is_local && !remove_all && i ) return(1);
- X if( Is_root && !Is_local && same_host && remove_all ) return(1);
- X if( Is_root && !Is_local && same_host && !remove_all && i ) return(1);
- X if( strcmp( Person, q->q_user) == 0 && same_host && i ) return(1);
- X if( i && control_perms ) return(1);
- X return( 0 );
- X}
- X
- X/***************************************************************************
- X * doremove(struct queue *q)
- X * remove the job
- X * 1. Lock the control file.
- X * 2. If unsuccessful, find the server PID and kill it off.
- X * 3. Use brute force and remove the files.
- X ***************************************************************************/
- X
- doremove( q )
- X struct queue *q;
- X{
- X FILE *cfp;
- X
- X if( (cfp = Lockcf( q->q_name )) == NULL ){
- X /* hmmm... looks like an active server */
- X if( (cfp = fopen_daemon( q->q_name, "r" )) == NULL ){
- X /* nope, the file has really gone */
- X logerr(XLOG_INFO,"control file %s not readable", q->q_name );
- X return;
- X }
- X /* well, we will just have to kill of the server */
- X if( q->q_daemon == 0){
- X /*
- X * Hmmm... we have this fellow running the file, and it is
- X * locked. That means that it just started running this
- X * guy. Better check again.
- X */
- X (void)Checkactive();
- X }
- X if( q->q_daemon ){
- X (void)fprintf( stdout, "killing off %s server %d",
- X q->q_server,q->q_daemon );
- X if( killpg( q->q_daemon, SIGINT) < 0 ){
- X if(Debug>2)log(XLOG_DEBUG,
- X "server %s (%d) was not alive",
- X q->q_server,q->q_daemon );
- X }
- X }
- X }
- X /* use brute force; we simply remove files */
- X if(Debug>3)log(XLOG_DEBUG,"removing files for job %s",q->q_name);
- X Remove_job( cfp, q );
- X (void)fclose( cfp );
- X}
- END_OF_FILE
- if test 7416 -ne `wc -c <'src/rmjob.c'`; then
- echo shar: \"'src/rmjob.c'\" unpacked with wrong size!
- fi
- # end of 'src/rmjob.c'
- fi
- echo shar: End of archive 5 \(of 16\).
- cp /dev/null ark5isdone
- 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
-
-