rsalz@uunet.uu.net (Rich Salz) (09/15/88)
Submitted-by: papowell@julius.cs.umn.edu Posting-number: Volume 16, Issue 19 Archive-name: plp/part06 #! /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 6 (of 16)." # Contents: filters/pf_main.c src/checkperm.c src/displayq.c src/lpc.c # src/lpq.c src/lpr_job.c # Wrapped by papowell@attila on Wed Aug 10 10:44:55 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'filters/pf_main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'filters/pf_main.c'\" else echo shar: Extracting \"'filters/pf_main.c'\" \(8221 characters\) sed "s/^X//" >'filters/pf_main.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: pf_main.c for prefilters X *************************************************************************** X * Revision History: Created Fri Mar 4 19:45:03 CST 1988 X * $Log: pf_main.c,v $ X * Revision 2.1 88/05/09 10:12:12 papowell X * *** empty log message *** X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: pf_main.c,v 2.1 88/05/09 10:12:12 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X/*************************************************************************** X * UMN-LPR prefilter template and frontend. X * X * A prefilter is invoked with the following parameters, X * which can be in any order, and perhaps some missing. X * X * filtername arguments \ <- from PRINTCAP entry X * -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \ X * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ X * -Fformat -Ddebug files X * X * 1. Parameters can be in different order than the above. X * 2. Optional parameters can be missing X * 3. Values specified for the width, length, etc., are from PRINTCAP X * or from the overridding user specified options. X * X * This program provides a common front end for most of the necessary X * grunt work. This falls into the following classes: X * 1. Parameter extraction. X * 2. Picking off files. X * The front end will extract parameters, then call the prefilter(file) X * routine, which is responsible for carrying out the required prefilter X * actions. X * X * The prefilter() routine should return 0 (success), 1 (retry) or 2 (abort). X * X * Parameter Extraction X * The main() routine will extract parameters X * whose values are placed in the appropriate variables. This is done X * by using the ParmTable[], which has entries for each valid letter X * parmeter, such as the letter flag, the type of variable, X * and the address of the variable. X * The following variables are provided as a default set. X * -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \ X * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ X * -Fformat files X * VARIABLE FLAG TYPE PURPOSE / PRINTCAP ENTRTY X * name name of filter char* argv[0], program identification X * width -wwidth int PW, width in chars X * length -llength int PL, length in lines X * xwidth -xwidth int PX, width in pixels X * xlength -xlength int PY, length in pixels X * literal -c int if set, ignore control chars X * indent -iindent int indent amount (depends on device) X * zopts -Zoptions char* extra options for printer X * class -Cclass char* classname X * job -Jjob char* jobname X * accntname -Raccntname char* account for billing purposes X * login -nlogin char* login name X * host -hhost char* host name X * format -Fformat char* format X * accntfile file char* AF, accounting file X * X * debug - sets debug level X * X * The functions fatal(), logerr(), and logerr_die() can be used to report X * status. The variable errorcode can be set by the user before calling X * these functions, and will be the exit value of the program. Its default X * value will be 2 (abort status). X * fatal() reports a fatal message, and terminates. X * logerr() reports a message, appends information indicated by errno X * (see perror(2) for details), and then returns. X * logerr_die() will call logerr(), and then will exit with errorcode X * status. X * Both fatal() and logerr_die() call the cleanup() function before exit. X * X * DEBUGGING: a simple minded debugging version can be enabled by X * compiling with the -DDEBUG option. X */ X X#include <stdio.h> X#include <signal.h> X#include <sys/file.h> X int errorcode = 2; X char *name; /* name of filter */ X/* set from flags */ int debug, width, length, xwidth, ylength, literal, indent; char *zopts, *class, *job, *login, *accntname, *host, *format; char *printer; int optind; X main( argc, argv ) X int argc; X char **argv; X{ X int i; X X getargs( argc, argv ); X X /* X * Turn off SIGPIPE X */ X (void)signal( SIGPIPE, SIG_IGN ); X errorcode = 0; X for( i = optind; i < argc; ++ i ){ X errorcode = prefilter( argv[i] ); X } X return(errorcode); X} X X/*VARARGS1*/ log(msg, a1, a2, a3) X char *msg; X{ X (void)fprintf(stderr, "%s: ", name); X (void)fprintf(stderr, msg, a1, a2, a3); X (void)putc('\n', stderr); X (void)fflush(stderr); X} X X/*VARARGS1*/ fatal(msg, a1, a2, a3) X char *msg; X{ X log(msg, a1, a2, a3); X cleanup(); X exit(errorcode); X} X X/*VARARGS1*/ logerr(msg, a1, a2, a3) X char *msg; X{ X extern int errno, sys_nerr; X extern char *sys_errlist[]; X int err = errno; X X (void)fprintf(stderr, "%s: ", name); X if (msg){ X (void)fprintf(stderr, msg, a1, a2, a3); X (void)fputs( "- ", stderr); X } X if( err < sys_nerr ){ X (void)fputs(sys_errlist[err]); X } else { X (void)fprintf(stderr, "Unknown error %d", err); X } X (void)putc('\n', stderr); X (void)fflush(stderr); X} X X/*VARARGS1*/ logerr_die(msg, a1, a2, a3) X char *msg; X{ X logerr(msg, a1, a2, a3); X cleanup(); X exit(errorcode); X} X getargs(argc, argv) X int argc; X char **argv; X{ X int i; /* argument index */ X char *arg; /* argument */ X int flag; /* flag */ X X name = argv[0]; X for( i = 1; i < argc; ++i ){ X arg = argv[i]; X if( *arg == '-' ){ /* arg will be string */ X setvar( arg[1], &arg[2] ); X } else { X optind = i; X break; X } X } X if( debug ){ X for( i = 0; i < argc; ++i ){ X fprintf(stdout, "%s ", argv[i] ); X } X fprintf( stdout, "\n" ); X printf("login '%s'\n", login? login : "null" ); X printf("host '%s'\n", host? host : "null" ); X printf("class '%s'\n", class? class : "null" ); X printf("format '%s'\n", format? format : "null" ); X printf("job '%s'\n", job? job : "null" ); X printf("printer '%s'\n", printer? printer : "null" ); X printf("accntname '%s'\n", accntname? accntname : "null" ); X printf("zopts '%s'\n", zopts? zopts : "null" ); X printf("literal, %d\n", literal); X printf("indent, %d\n", indent); X printf("length, %d\n", length); X printf("width, %d\n", width); X printf("xwidth, %d\n", xwidth); X printf("ylength, %d\n", ylength); X for( i = 0; i < argc; ++i ){ X fprintf(stderr, "%s ", argv[i] ); X } X fprintf( stderr, "\n" ); X fflush(stderr); X fflush(stdout); X } X} X X#define INTV 0 X#define STRV 1 X#define FLGV 2 struct parm { X int flag; X char **var; X int kind; X} Parmlist[] = { X{'C', &class, STRV }, X{'D', (char **)&debug, INTV }, X{'F', &format, STRV }, X{'J', &job, STRV }, X{'P', &printer, STRV }, X{'R', &accntname, STRV }, X{'Z', &zopts, STRV }, X{'c', (char **)&literal, FLGV }, X{'h', &host, STRV }, X{'i', (char **)&indent, INTV }, X{'l', (char **)&length, INTV }, X{'n', &login, STRV }, X{'w', (char **)&width, INTV }, X{'x', (char **)&xwidth, INTV }, X{'y', (char **)&ylength, INTV } }; X int Parmlen = sizeof(Parmlist)/sizeof(struct parm); X X/* X * setvar( int flag, char *arg ) X * 1. look in table and find entry X * 2. if STRV, then set X * 3. if INTV, then convert and set X * 4. if FLGV, then set to 1 X */ setvar( flag, arg ) X int flag; X char *arg; X{ X int u, l, i, c; /* upper, lower, i */ X X l = 0; u = Parmlen; X while( l <= u ){ X i = (u+l)/2; X c = flag - Parmlist[i].flag; X if( 0 == c ){ X /* printf( "found parm %c, %d\n", flag, i ); */ X switch( Parmlist[i].kind ){ X case STRV: *Parmlist[i].var = arg; break; X case INTV: *(int *)Parmlist[i].var = atoi(arg); break; X case FLGV: *(int *)Parmlist[i].var = 1; break; X } X return; X } else if( c < 0 ){ X /* printf( "down parm %c, %d\n", flag, i ); */ X u = i - 1 ; X } else { X /* printf( "up parm %c, %d\n", flag, i ); */ X l = i + 1 ; X } X } X /* printf( "did not find parm %c, %d\n", flag, i ); */ X return; X} X X#ifdef DEBUG cleanup() {} X prefilter( file ) X char *file; X{ X FILE *fp; X int c; X X log( "file %s", file ); X if( (fp = fopen( file, "r" )) == NULL ){ X fatal( "cannot open file %s", file ); X } X while( (c = getc(fp)) != EOF ){ X putchar(c); X } X} X#endif DEBUG END_OF_FILE if test 8221 -ne `wc -c <'filters/pf_main.c'`; then echo shar: \"'filters/pf_main.c'\" unpacked with wrong size! fi # end of 'filters/pf_main.c' fi if test -f 'src/checkperm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/checkperm.c'\" else echo shar: Extracting \"'src/checkperm.c'\" \(8361 characters\) sed "s/^X//" >'src/checkperm.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: Checkperm.c X * printer permission checking X *************************************************************************** X * Revision History: Created Sun Jan 3 19:08:26 CST 1988 X * $Log: checkperm.c,v $ X * Revision 3.1 88/06/18 09:33:59 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.4 88/05/27 08:27:23 papowell X * Fixed the '~' permissions line X * X * Revision 2.3 88/05/21 10:26:22 papowell X * Added check for '~' or always X * X * Revision 2.2 88/05/16 09:44:32 papowell X * Modified match() to handle null strings better X * X * Revision 2.1 88/05/09 10:07:46 papowell X * PLP: Released Version X * X * Revision 1.3 88/04/07 09:11:14 papowell X * Modified 'while' loop; removed break X * X * Revision 1.2 88/03/25 14:59:09 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.1 88/03/01 11:08:18 papowell X * Initial revision X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: checkperm.c,v 3.1 88/06/18 09:33:59 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X/****************************************************************************** X * Checkperm - determine if a user has permissions to act on a printer queue X * X * Input: X * permfile - name of the permissions file, X * each line of which has the form: X * hostname userid printer_name op pr max current X * hostname - the host name of the invoker X * userid - the user name of the invoker X * printer_name - the printer queue to be checked X * op -the maximum operation level, A is 'Highest', Z is 'lowest' X * Note: R is for LPR, C is for LPC, * allows all X * pr - the maximum priority level, A is 'Highest', Z is 'lowest' X * max - max number of pages allowed X * current - current number of pages X * X * # -- comment X * #hostname username printername op pr maxpages currentpages X * attila papowell imagen C A 1000 100 X * !* cs9* lpr * * X * * jsmith imagen * * 0 0 X * * root * * * X * X * Note: * is the wildcard indicator and matches all characters X * Note: if maxpages == 0, then page count is unlimited. X * Note: if a ! is in the first column and there is a match X * (i.e.- we should grant permission), then permission is refused. X * In the example above, this prevents users whose names start with X * cs9 will be forbidden access to the lpr queue. X * X * Output: X * 0 - if userid does not have permissions to act on printer queue X * nonzero - permission granted X * X * If any of arguments is not specified (i.e.- 0 or NULL value), X * then checking is not done for the field. X *****************************************************************************/ X X#include "lp.h" X int Checkperm(permfile, host, user, printerq, op, pr_level, pages) X char *permfile; /* file to read for permissions */ X char *host; /* hostname to check for */ X char *user; /* username to check for */ X char *printerq; /* printername to check for */ X int *op; /* operation level to check for */ X int *pr_level; /* priority level to check for */ X int pages; /* check page limits flag */ X{ X FILE *fp; X int i; X char buf[BUFSIZ]; X char username[MAXPARMLEN+1]; X char hostname[MAXPARMLEN+1]; X char printerqname[MAXPARMLEN+1]; X char priority[MAXPARMLEN+1]; X char operation[MAXPARMLEN+1]; X char *str; X int max, current; X int permission = 0; X int invert, must, found; X X must = 0; X invert = 0; X if( permfile == 0 ){ X logerr( XLOG_INFO, "Checkperm: no perm file" ); X return(permission); X } X if(Debug>5)log(XLOG_DEBUG, X "Checkperm file %s,host=%s,user=%s,printerq=%s,op=%c,pr_level=%c,pages=%d", X permfile, host?host:"NONE", user?user:"NONE", printerq?printerq:"NONE", X op?*op:'?', pr_level?*pr_level:'?', pages); X /* X * open permfile for reading X */ X if((fp = fopen_daemon(permfile,"r")) == NULL){ X logerr( XLOG_CRIT, "Checkperm: cannot open perms file %s",permfile); X return(permission); X } X X /* X * scan through the file looking for a match X */ X found = 0; X while( found == 0 && fgets( buf, sizeof(buf), fp ) != NULL ){ X /* read in the host name */ X /* sscanf returns number of fields converted */ X if( buf[0] == '\n' || buf[0] == '#' ){ X continue; X } X must = 0; X invert = 0; X max = current = 0; X priority[0] = 0; X operation[0] = 0; X str = buf; X switch( buf[0] ){ X case '!': invert = 1; ++str; break; X case '~': must = 1; ++str; break; X } X i = sscanf(str, "%s%s%s%s%s%d%d", hostname, username, X printerqname,operation,priority,&max,¤t); X if( i == 0 ){ X continue; X } else if( i < 4 ){ X log(XLOG_CRIT, X "Error in %s, '%s'\n Please inform system guru.", permfile, buf); X (void)fclose(fp); X return(permission); X } X if(Debug>6)log(XLOG_DEBUG, X "host=%s,user=%s,printer=%s,oper=%s,priority=%s,max%d,current%d", X hostname, username, printerqname,operation,priority,max,current ); X X /* X * if the hostname field is '*', this means any host can do it X * otherwise we should check to see if a valid host name X */ X if( !match(host,hostname) ){ X if( must ){ X found = 1; X } X continue; X } X if(Debug>6)log(XLOG_DEBUG, "Checkperm: host ok, %s, %s", X host?host:"<NONE>",hostname); X X /* compare the user names */ X if( !match(user,username) ){ X if( must ){ X found = 1; X } X continue; X } X if(Debug>6)log(XLOG_DEBUG, "Checkperm: user ok, %s, %s", X user?user:"<NONE>",username); X X /* compare the printer queue names */ X if( !match(printerq,printerqname) ){ X if( must ){ X found = 1; X } X continue; X } X if(Debug>6)log(XLOG_DEBUG, "Checkperm: printerq ok, %s, %s", X printerq?printerq:"<NONE>",printerqname); X X /* compare the operations */ X if( op && operation[0] != '*' && *op < operation[0]){ X if( must ){ X found = 1; X } X continue; X } X if(Debug>6)log(XLOG_DEBUG, X "Checkperm: OK, must %d, wanted %c(%d), have %c(%d), invert %d", X must, op?*op:'?', op?*op:'?', operation[0], operation[0], invert); X /* X * Well, you had to have a match, and you did. So this means that X * you passed, but you do not use this entry. X */ X if( must ){ X continue; X } X if(Debug>6)log(XLOG_DEBUG, X "Checkperm: pages- %d, max %d, current %d", pages,max,current); X found = 1; X permission = 1; X if( pages && max && current > max ){ X /* page limit exceeded in first matching entry: bad news */ X permission = 0; X } X if( pr_level && priority[0] && priority[0] != '*'){ X /* we want to check priory and there are limits */ X if( priority[0] > *pr_level ){ X /* sorry, this is too high */ X *pr_level = priority[0]; X } X } X } X if( permission && invert ){ X permission = 0; X } X if(Debug>4)log(XLOG_DEBUG,"Checkperm %d in %s, printerq %s for %s@%s", X permission, permfile, X printerq?printerq:"NONE",user?user:"NONE",host?host:"NONE"); X (void)fclose(fp); X return(permission); X} X X/* X * match( str, pattern ) X * -- str is null (match returns 1 ) X * -- pattern is <fixed>*, str is <fixed><anything> (match returns 1) X * -- pattern is !<fixed>*, str is <fixed><anything> (match returns 0) X * -- if not above, match returns 0 X */ X static int match( str, pattern) X char *str, *pattern; X{ X int c; X X if(Debug>8)log(XLOG_DEBUG,"match str '%s', pattern '%s'\n", str, pattern ); X if( str == 0 || pattern == 0) return(1); X while( c = *pattern ){ X if(Debug>8)log(XLOG_DEBUG,"match partial str '%s', pattern '%s'\n", X str, pattern ); X switch( c ){ X /* X * match 0 or more characters in the string X */ X case '*': X if( match( str, pattern+1 ) ){ X return( 1 ); X } X if( *str && match( str+1, pattern ) ){ X return( 1 ); X } X return( 0 ); X case '?': X if( *str == 0 ){ X return( 0 ); X } X break; X default: X if( c != *str ){ X return( 0 ); X } X break; X } X ++pattern; ++str; X } X return( *pattern == *str ); X} END_OF_FILE if test 8361 -ne `wc -c <'src/checkperm.c'`; then echo shar: \"'src/checkperm.c'\" unpacked with wrong size! fi # end of 'src/checkperm.c' fi if test -f 'src/displayq.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/displayq.c'\" else echo shar: Extracting \"'src/displayq.c'\" \(7973 characters\) sed "s/^X//" >'src/displayq.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: displayq.c X * Display the status of a Printer queue X *************************************************************************** X * Revision History: Created Sat Jan 9 20:08:26 CST 1988 X * $Log: displayq.c,v $ X * Revision 3.1 88/06/18 09:34:07 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.3 88/05/16 12:09:08 papowell X * Added a queue printing, spooling message X * X * Revision 2.2 88/05/14 10:17:57 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:07:58 papowell X * PLP: Released Version X * X * Revision 1.6 88/04/06 12:13:18 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.5 88/03/25 14:59:21 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.4 88/03/12 10:03:25 papowell X * *** empty log message *** X * X * Revision 1.3 88/03/11 19:28:04 papowell X * Minor Changes, Updates X * X * Revision 1.2 88/03/05 15:01:25 papowell X * Minor Corrections, Lint Problems X * X * Revision 1.1 88/03/01 11:08:21 papowell X * Initial revision X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: displayq.c,v 3.1 88/06/18 09:34:07 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X X#include "lp.h" static int header; static int server; X X/*************************************************************************** X * Displayq() 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. print the queue status X ***************************************************************************/ X Displayq() X{ X int i; /* ACME Integers, Inc. */ X struct queue *q; /* job entry */ X char buf[BUFSIZ]; /* status message buffer */ X X header = 0; 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>0)log(XLOG_DEBUG,"Printer %s does not have a spool queue\n", X Printer); X return; X } X X if(Debug>5)log(XLOG_DEBUG,"Displayq: doing %s", Printer ); X /* X * If you are running NFS, use the remote lpr X */ X if( RM && *RM && NW ){ X Remote_status(); 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 * get the numbers of jobs here X */ X Jobcount = Getq(); X /* X * Checkactive checks for the active jobs X */ X server = Checkactive(); X buf[0] = 0; X if( LO_statb.st_mode & DISABLE_QUEUE ){ X (void)strcat(buf, "no spooling" ); X } X if( LO_statb.st_mode & DISABLE_PRINT ){ X if( buf[0] ){ X (void)strcat( buf, ", "); X } X (void)strcat(buf, "no printing" ); X } X X if( Short_format ){ X if( From == Host ){ X (void)fprintf(stdout,"%s: %d jobs", Printer, Jobcount ); X } else { X (void)fprintf(stdout,"%s@%s: %d jobs", Printer, Host, Jobcount ); X } X if( buf[0] ){ X (void)fprintf(stdout," (%s)", buf ); X } X (void)fprintf(stdout,"\n"); X } else { X if( From == Host ){ X if( SV == 0 || *SV == 0 ){ X (void)fprintf(stdout, "Printer '%s' (%s):", Printer, Host ); X } else { X (void)fprintf(stdout, "Queue '%s' (%s):", Printer, Host ); X } X if( buf[0] ){ X (void)fprintf(stdout," (%s)", buf ); X } X (void)fprintf(stdout,"\n"); X } else { X if( SV == 0 || *SV == 0 ){ X (void)fprintf(stdout, "Remote printer '%s' (%s):",Printer,Host); X } else { X (void)fprintf(stdout, "Remote queue '%s' (%s):", Printer, Host ); X } X if( buf[0] ){ X (void)fprintf(stdout," (%s)", buf ); X } X (void)fprintf(stdout,"\n"); X } X /* X * show status files X */ X showstatus(); X } X (void)fflush(stdout); X /* X * run down list X */ X for( i = 0; i < Jobcount; ++i ){ X q = &Queue[i]; X if( Parmcount <= 0 || Match_entry( q ) ){ X showentry(i+1, q); X } X } X if( RM && *RM ){ X Remote_status(); X } X if( From == Host ){ X putchar('\n'); X } X} X X/***************************************************************************** X * showentry( int seq, struct queue *q ) X * show status for entry X * Rank Owner Pr Job Host Files Size X * active sutantha Z 260 umn-cs (stdin) 177744 bytes X * 2 powell Z 1 attila junk, morejunk,... 32767 bytes X * X * if you have multiple servers, the first column will contain the name X * of the server. X * Rank Owner Pr Job Host Files Size X * sv1 sutantha Z 260 umn-cs (stdin) 177744 bytes X * sv2 powell Z 1 attila junk, morejunk,... 32767 bytes X *****************************************************************************/ X static char hdr_format[] = "%6s %-11s %-2s %-3s %-11s %-20s %-6s %-s\n"; static char info_format[] = "%6s %-11s %-c %-3d %-11s %-20s %-6d %s\n"; X static char * short_time( tvec ) X time_t tvec; /* time */ X{ X char *ctime(); X static char s[40]; X X /* X * 012345678901234567890123456789 X * Mon May 30 20:53:27 CDT 1988 X */ X (void)strcpy(s,ctime(&tvec)); X s[16] = 0; X return( &s[4] ); X} showentry( seq, q ) X int seq; X struct queue *q; X{ X char buf[10]; X char *suffix; X char name[BUFSIZ]; X char date[BUFSIZ]; X X if( Short_format ){ X (void)fprintf(stdout,"%d %s: %s\n", seq, q->q_name, q->q_user ); X (void)fflush(stdout); X return; X } X if( header == 0 ){ X (void)fprintf(stdout, hdr_format,"Rank","Owner","Pr","Job", X "Host","Files","Size","Date"); X header = 1; X } X if( q->q_daemon ){ X if( SV == 0 || *SV == 0 ){ X (void)strcpy( buf, "active" ); X } else { X (void)strcpy( buf, q->q_server ); X } X } else { X switch( seq ){ X case 1: suffix = "st"; break; X case 2: suffix = "nd"; break; X case 3: suffix = "rd"; break; X default: suffix = "th"; break; X } X (void)sprintf(buf, "%d%s", seq, suffix ); X } X /* X * print short name X */ X (void)strcpy(name, &q->q_from ); X suffix = index( name, '.' ); X if( suffix ){ X *suffix = 0; X } X (void)fprintf(stdout, info_format, buf, q->q_user, q->q_priority, q->q_num, X name,q->q_data, q->q_size, short_time(q->q_sp) ); X (void)fflush(stdout); X} X X/* X * show status: X * show the status files for the server devices X */ showstatus() X{ X static char server_name[BUFSIZ]; /* Name of server file */ X int active, pid; X char buf[BUFSIZ]; X char *sp, *ep; /* ACME Pointer */ X X if( SV == 0 || *SV == 0 ){ X if( Jobcount > 0 && server == 0 ){ X (void)fprintf(stdout, "Warning: no server present\n" ); X } X printstatus(); X return; X } X /* X * check for each of the servers X */ X (void)strcpy( server_name, SV ); X for( sp = server_name; sp; sp = ep ){ X if( ep = index( sp, ',' ) ){ X *ep = 0; X ++ep; X } X /* X * get the lock file and the status from the server X */ X if( Set_pc_entry( sp, Server_pc_vars, Server_pc_len ) == 0 ){ X fatal( XLOG_INFO, "no server entry for %s", sp ); X } X buf[0] = 0; X active = Checklockfile( sp, &pid,buf,sizeof(buf),&LO_statb ); X (void)fprintf(stdout, " server- %s", sp ); X if( LO_statb.st_mode & DISABLE_PRINT ){ X (void)fprintf(stdout, " disabled"); X } else { X (void)fprintf(stdout, " enabled"); X } X if( active ){ X (void)fprintf(stdout, ", server %d, processing %s",pid, buf ); X } X putchar( '\n' ); X (void)fflush( stdout ); X printstatus(); X } X} X END_OF_FILE if test 7973 -ne `wc -c <'src/displayq.c'`; then echo shar: \"'src/displayq.c'\" unpacked with wrong size! fi # end of 'src/displayq.c' fi if test -f 'src/lpc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/lpc.c'\" else echo shar: Extracting \"'src/lpc.c'\" \(8375 characters\) sed "s/^X//" >'src/lpc.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: lpc.c X * lpc - control LPR queues X *************************************************************************** X * Revision History: Created Mon Jan 25 14:04:26 CST 1988 X * $Log: lpc.c,v $ X * Revision 3.1 88/06/18 09:34:36 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.2 88/05/14 10:21:01 papowell X * Modified -X flag handling X * X * Revision 2.1 88/05/09 10:08:40 papowell X * PLP: Released Version X * X * Revision 1.7 88/04/27 18:02:54 papowell X * The SIGCHLD signal has an odd behaviour on some systems. Modified so that X * it will not get set UNLESS processes are started; also, it is reset X * to SIG_DFL, not SIG_IGN. X * X * Revision 1.6 88/04/15 13:06:23 papowell X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr) X * have valid file descriptors; if not open, then /dev/null is used. X * X * Revision 1.5 88/04/07 12:32:26 papowell X * Modified to use Getopt X * X * Revision 1.4 88/04/06 12:12:17 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.3 88/03/25 15:00:00 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/11 19:28:21 papowell X * Minor Changes, Updates X * X * Revision 1.1 88/03/01 11:08:35 papowell X * Initial revision X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: lpc.c,v 3.1 88/06/18 09:34:36 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X#include "lp.h" X X X/*************************************************************************** X * SYNOPSIS X * lpc [ -Dn ] [ -X [ command [ argument ... ] ] X * DESCRIPTION X * Lpc is used by the system administrator to control the X * operation of the line printer system. For each line printer X * configured in /etc/printcap, lpc may be used to: X * + disable or enable a printer, X * + disable or enable a printer's spooling queue, X * + rearrange the order of jobs in a spooling queue, X * + find the status of printers, and their associated spooling X * queues and printer dameons. X * Without any arguments, lpc will prompt for commands from the X * standard input. If arguments are supplied, lpc interprets X * the first argument as a command and the remaining arguments X * as parameters to the command. The standard input may be X * redirected causing lpc to read commands from file. Commands X * may be abreviated; the following is the list of recognized X * commands. X * ? [ command ... ] X * help [ command ... ] X * abort { all | printer ... } X * clean { all | printer ... } X * enable { all | printer ... } X * exit X * quit X * disable { all | printer ... } X * restart { all | printer ... } X * start { all | printer ... } X * kill { all | printer ... } X * status [ terse ] [ all ] [ printer ... ] X * stop { all | printer ... } X * remote { abort | clean | enable | disable | restart } printer X * topq printer [ jobnum ... ] [ user ... ] X * lpq [options] X * lprm [options] X * lpd X * X * -Dn Enables display of debugging information. The -D X * selects level 1; -Dn selects level n (n is a single X * digit). X * -X Use an Xperimental version of LPD if the software has X * been compiled with the appropriate support; ignored X * otherwise. X ***************************************************************************/ X/*************************************************************************** X * main(int argc, char **argv) X * 1. get the host computer name and user name X * 2. set up the Host and Person information X * 3. get the parameters or set up a read from STDIN X * 4. convert parameters and call the server routine X ****************************************************************************/ X extern int cleanup(); X main(argc, argv) X int argc; X char **argv; X{ X struct passwd *pw_ent; /* user entry in /etc/passwd */ X X /* X * set umask to avoid problems with user umask X */ X (void)umask(0); X /* X * Set fd 0, 1, 2 to /dev/null if not open X */ X Std_environ(); X# ifdef XPERIMENT X Setup_test(); X# endif XPERIMENT X X /* X * set up the pathnames for information files X */ X Tailor_names(); X /* X * set the from flag X */ X From = Host; X /* X * get the user name X */ X if( (pw_ent = getpwuid( getuid() )) == 0 ){ X logerr_die( XLOG_INFO, "lpc: getpwuid failed on uid %d", getuid()); X } X (void)strcpy( LOGNAME, pw_ent->pw_name ); X Person = LOGNAME; X if( getuid() == 0 ){ X /* we are being invoked by root */ X Is_root = 1; X } X /* X * setup parameters X */ X Lpc_parms(argc, argv); X /* X * set signals X */ X (void)signal(SIGPIPE, SIG_IGN); X (void)signal(SIGHUP, cleanup); X (void)signal(SIGINT, cleanup); X (void)signal(SIGQUIT, cleanup); X (void)signal(SIGTERM, cleanup); X if( Parmcount != 0 ){ X (void)Control_ops(); X } else { X Get_line(); X } X exit( 0 ); X} X X/*************************************************************************** X * cleanup() X * remove the temp files X ***************************************************************************/ X cleanup() X{ X exit( 1 ); X} X X/*************************************************************************** X * Lpc_parms( int arc, char **argv ) X * 1. pick off the options X * 2. set up the parameters X ***************************************************************************/ X static char *optstr = "D:X"; static int Xpert; Lpc_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 'D': X if(Debug){ X Diemsg("Duplicate -D option"); X } X if( sscanf( Optarg, "%d", &Debug ) != 1 || Debug <= 0){ X Diemsg("-D parameter is not positive integer" ); X } X break; X case 'X': X if( Xpert ){ X Diemsg("Duplicate -X option"); X } X# ifdef DEBUG X Setup_test(); X Tailor_names(); X# else X Diemsg("-X is not allowed" ); X# endif DEBUG X break; X default: X break; 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 i = atoi( Parms[Parmcount].str ); X if( i > 0 ){ X Parms[Parmcount].num = i; X } else { X Parms[Parmcount].num = -1; X } X ++Parmcount; X } else { X Diemsg( "too many parameters" ); X } X } X} X X X/*************************************************************************** X * Get_line() X * Repeat: X * 1. Get a line. X * 2. if EOF return X * 3. Split it up and put into Parms[] X * 4. Call Control_ops() X ***************************************************************************/ X Get_line() X{ X char buf[BUFSIZ]; /* get a line */ X int i; /* ACME Integers, Inc. */ X char *cp; /* ACME Pointers, Inc. */ X X while( 1 ){ X (void)fprintf(stdout, "lpc>"); X (void)fflush(stdout); X if( fgets( buf, sizeof(buf), stdin ) == 0 ) return; X buf[ strlen(buf) -1 ] = 0; /* clobber the last char */ X /* X * now set up the parameters X */ X Parmcount = 0; X for( cp = buf; *cp; ){ X /* skip leading blanks */ X Parms[Parmcount].str = 0; X Parms[Parmcount].num = -1; X while( *cp && isspace( *cp ) ) ++cp; X if( *cp ){ X Parms[Parmcount].str = cp; X } X while( *cp && !isspace( *cp ) ) ++cp; X if( *cp ){ X *cp = 0; X ++cp; X } X if( Parms[Parmcount].str != 0 ){ X Parms[Parmcount].num = -1; X i = atoi( Parms[Parmcount].str ); X if( i > 0 ){ X Parms[Parmcount].num = i; X } X ++Parmcount; X } X } X if( Parmcount ){ X if(Debug>3){ X for( i = 0; i < Parmcount; ++i ){ X (void)fprintf(stderr,"Parms[%d]: '%s', %d\n",i, X Parms[i].str,Parms[i].num ); X } X } X (void)Control_ops(); X } X } X /*NOTREACHED*/ X} END_OF_FILE if test 8375 -ne `wc -c <'src/lpc.c'`; then echo shar: \"'src/lpc.c'\" unpacked with wrong size! fi # end of 'src/lpc.c' fi if test -f 'src/lpq.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/lpq.c'\" else echo shar: Extracting \"'src/lpq.c'\" \(8037 characters\) sed "s/^X//" >'src/lpq.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: lpq.c X *************************************************************************** X * Revision History: Created Mon Feb 1 11:34:11 CST 1988 X * $Log: lpq.c,v $ X * Revision 3.2 88/07/01 15:44:39 papowell X * Added multiple -P parameters X * X * Revision 3.1 88/06/18 09:34:43 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.2 88/05/14 10:20:56 papowell X * Modified -X flag handling X * X * Revision 2.1 88/05/09 10:08:54 papowell X * PLP: Released Version X * X * Revision 1.7 88/04/28 11:03:01 papowell X * removed unused variables, shuts up lint X * X * Revision 1.6 88/04/27 18:02:50 papowell X * The SIGCHLD signal has an odd behaviour on some systems. Modified so that X * it will not get set UNLESS processes are started; also, it is reset X * to SIG_DFL, not SIG_IGN. X * X * Revision 1.5 88/04/15 13:06:14 papowell X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr) X * have valid file descriptors; if not open, then /dev/null is used. X * X * Revision 1.4 88/04/07 12:26:49 papowell X * modified to use Getopt X * X * Revision 1.3 88/03/25 15:00:11 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/11 19:28:16 papowell X * Minor Changes, Updates X * X * Revision 1.1 88/03/01 11:08:39 papowell X * Initial revision X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: lpq.c,v 3.2 88/07/01 15:44:39 papowell Locked $ PLP Copyright 1988 Patrick Powell"; X#endif lint X#include "lp.h" X X/*************************************************************************** X * lpq - spool queue examination program X * lpq [-Pprinter ][-a][-l][+[n]][-D[n]][-X][ job # ... ][ user ... ] X * DESCRIPTION X * lpq examines the spooling area used by lpd(8) for printing X * files on the line printer, and reports the status of the X * specified jobs or all jobs associated with a user. lpq X * invoked without any arguments reports on the printer given X * by the default printer (see -P option). For each job sub- X * mitted (i.e. invocation of lpr(1)) lpq reports the user's X * name, current rank in the queue, the names of files compris- X * ing the job, the job identifier (a number which may be sup- X * plied to lprm(1) for removing a specific job), and the total X * size in bytes. Job ordering is dependent on the algorithm X * used to scan the spooling directory and is FIFO (First in X * First Out), in order of priority level. File names compris- X * ing a job may be unavailable (when lpr(1) is used as a sink X * in a pipeline) in which case the file is indicated as X * ``(stdin)''. The following options are available. X * -P printer spool queue name X * -a All printers listed in /etc/printcap(5) file are reported. X * -l aLternate display format X * [+[n]] redisplay the spool queue X * -D[n] debug level n X * -X Use an Xperimental version of LPD X * [ job # ... ][ user ... ] X ***************************************************************************/ X static int Delay; /* time to wait */ static int Do_all_pr; /* do all printers */ static int Xpert; /* X flag */ static char **Printer_name; static int Printer_count; static int Max_printer_count; int cleanup(); X main( argc, argv ) X int argc; X char **argv; X{ X struct passwd *pw_ent; /* user entry in /etc/passwd */ X int i; X X /* X * set umask to avoid problems with user umask X */ X (void)umask(0); X /* X * Set fd 0, 1, 2 to /dev/null if not open X */ X Std_environ(); X# ifdef XPERIMENT X Setup_test(); X# endif XPERIMENT X X /* X * set up the pathnames for information files X */ X Tailor_names(); X /* X * set up the from information X */ X From = Host; X /* X * get the user name X */ X if( (pw_ent = getpwuid( getuid() )) == 0 ){ X logerr_die( XLOG_INFO, "getpwuid failed on uid %d", getuid()); X } X (void)strcpy( LOGNAME, pw_ent->pw_name ); X Person = LOGNAME; X /* X * get the parameters X */ X Get_parms(argc, argv); X (void)signal(SIGPIPE, SIG_IGN); X (void)signal(SIGHUP, cleanup); X (void)signal(SIGINT, cleanup); X (void)signal(SIGQUIT, cleanup); X (void)signal(SIGTERM, cleanup); X do{ X /* X * if we are to clear the terminal, do so X */ X if( Delay ){ X Term_clear(); X } X /* X * if we have all printers to display, do so X */ X if( Do_all_pr ){ X Display_all(); X } else if( Printer_count == 0 ){ X Displayq(); X } else { X for( i = 0; i < Printer_count; ++i ){ X Printer = Printer_name[i]; X Displayq(); X } X } X if( Delay ){ X sleep( (unsigned)Delay ); X } X } while( Delay ); X exit( 0 ); X} X X X/*************************************************************************** X * Get_parms( argc, argv ) X * 1. set up the name routine X * 2. extract parameters X * -Pprinter sets Printer to printer X * -Dn set Debug to n X * -a sets Do_all_pr X * -l set Short_format X * -X sets Xpert X * +nn X ***************************************************************************/ static char *optstr= "P:D:alX+?"; Get_parms( argc, argv ) X int argc; X char **argv; X{ X int c; /* ACME Integers, Inc. */ X char *arg; /* argument from list */ X X Opt_flag = "+"; X while( (c = Getopt(argc,argv,optstr)) != EOF ){ X switch( c ){ X case 'P': X if( Printer_count == Max_printer_count ){ X if( Max_printer_count == 0 ){ X Max_printer_count = 3; X Printer_name = X (char **)malloc( Max_printer_count * sizeof(char *)); X } else { X Max_printer_count += 3; X Printer_name = X (char **)realloc( Printer_name, X Max_printer_count * sizeof(char *)); X } X } X Printer_name[Printer_count] = Optarg; X ++Printer_count; X break; X case 'D': X Check_already( c, &Debug ); X if( Optarg ){ X Debug = atoi( Optarg ); X } else { X Debug = 1; X } X break; X case 'a': X Check_already( c, &Do_all_pr ); X break; X case 'l': X Check_already( c, &Short_format ); X break; X case 'X': X Check_already( c, &Xpert ); X# ifdef DEBUG X Setup_test(); X Tailor_names(); X# else X Diemsg( "-X not allowed" ); X# endif DEBUG X break; X case '+': X /************************************** X [+[n]] set Delay to n X **************************************/ X Check_already( c, &Delay ); X if( Optarg ){ X Delay = atoi( Optarg ); X } X if( Delay == 0 ){ X Delay = 30; X } X break; X default: X Usemsg(); X exit(1); X } X } X for(; Optind < argc; ++Optind ){ X arg = argv[Optind]; X Parms[Parmcount].str = arg; X if( isdigit( *arg ) ){ X Parms[Parmcount].num = atoi( arg ); X } else { X Parms[Parmcount].num = -1; X } X ++Parmcount; X if( Parmcount >= MAXPARMS ){ X Diemsg( "Too many arguments" ); X } X } X /* X * pick up the default printer name X */ X Get_Printer(0); X} X static Check_already( c, v ) X int c; X int *v; X{ X if( *v ){ X Usemsg(); X Diemsg( "-%c has already been specified", c); X } X *v = 1; X} X Usemsg() X{ X (void)fprintf(stderr, X "use: lpq [-Pprinter] [-alX] [+[n]] [-Dn] (job# | user)*\n"); X} X X/*************************************************************************** X * Display_all() X * 1. get the printer list X * 2. for each printer in the list call Displayq X ***************************************************************************/ X Display_all() X{ X char **list; X X for( list = All_printers(); *list; ++list ){ X Printer = *list; X Displayq(); X } X} X/*************************************************************************** X * cleanup() X * remove the temp files X ***************************************************************************/ X cleanup() X{ X Term_finish(); X exit( 1 ); X} END_OF_FILE if test 8037 -ne `wc -c <'src/lpq.c'`; then echo shar: \"'src/lpq.c'\" unpacked with wrong size! fi # end of 'src/lpq.c' fi if test -f 'src/lpr_job.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/lpr_job.c'\" else echo shar: Extracting \"'src/lpr_job.c'\" \(9221 characters\) sed "s/^X//" >'src/lpr_job.c' <<'END_OF_FILE' X/*************************************************************************** X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell X *************************************************************************** X * MODULE: lpr_job.c X * Submit job in the spool directory X *************************************************************************** X * Revision History: Created Sat Jan 30 18:11:41 CST 1988 X * $Log: lpr_job.c,v $ X * Revision 3.2 88/06/24 17:55:45 papowell X * MODS for VAX 4.3BSD UNIX X * X * Revision 3.1 88/06/18 09:34:57 papowell X * Version 3.0- Distributed Sat Jun 18 1988 X * X * Revision 2.1 88/05/09 10:09:19 papowell X * PLP: Released Version X * X * Revision 1.6 88/05/06 07:08:11 papowell X * Modified getwd() call so that a setreuid() is done first. This way there X * are no problems with root perms on different systems. X * X * Revision 1.5 88/05/05 20:07:24 papowell X * Minor changes to shut up lint. X * X * Revision 1.4 88/04/06 12:08:06 papowell X * Minor change, the 'A'printer control line not put in control file. X * This allows the existing version to send control files to older versions. X * X * Revision 1.3 88/03/25 15:00:35 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/11 19:28:08 papowell X * Minor Changes, Updates X * X * Revision 1.1 88/03/01 11:08:49 papowell X * Initial revision X * X ***************************************************************************/ X#ifndef lint static char id_str1[] = X "$Header: lpr_job.c,v 3.2 88/06/24 17:55:45 papowell Exp $ PLP Copyright 1988 Patrick Powell"; X#endif lint X X#include "lpr.h" X char *Make_link(); char *Full_path(); extern char *getwd(); X X X/*************************************************************************** X * Make_job() X * 1. Get a control file (actually a temp file) X * 2. Write the header information into the file X * 3. If you have a filter output, queue that X * 4. otherwise if you have a simple file, queue that X * 5. otherwise copy all of the files X ***************************************************************************/ X Make_job() X{ X char *cf; /* control file name */ X FILE *cfp; /* control file fp */ X int fd; /* data file fd */ X int i, c; /* ACME Integers, Inc. */ X long j, jobsize; /* jobsize is a long */ X char *s; /* ACME Pointers, Inc. */ X struct stat f_stat, c_stat; /* source and copy files status */ X X /* X * get the control file X */ X jobsize = 0; X cf = Get_cf(); X i = Open_SD( cf ); X if( (cfp = fdopen( i, "w")) == NULL ){ X logerr_die( XLOG_INFO, "Make_job: IMPOSSIBLE- fdopen failed %s",cf); X } X /* X * place in the time X */ X (void)sprintf( WHENSP, "%lu", (unsigned long)time( (time_t *)0 )); X /* X * Put entries in for each character in the Parms list X */ X for( i = 'A'; i <= 'Z'; ++i ){ X s = CFparm[i-'A']; X if( s[0] ){ X Entry( i, s, cfp ); X } X } X /* set the job name to the first file if not specified */ X if( Parmcount == 0 ){ X Entry( 'N', "(stdin)", cfp ); X if( JOBNAME[0] == 0 ){ X Entry( 'J', "(stdin)", cfp ); X } X } else { X for( i = 0; i < Parmcount; ++i ){ X if( Parms[i].str ){ X Entry( 'N', Parms[i].str, cfp ); X if( JOBNAME[0] == 0 ){ X Entry( 'J', Parms[i].str, cfp ); X JOBNAME[0] = 'X'; X } X } X } X } X /* set the class name to the priority if not specified */ X if( CLASSNAME[0] == 0 ){ X CLASSNAME[0] = Priority; X CLASSNAME[1] = 0; X Entry( 'C', CLASSNAME, cfp ); X } X /* X * put out the created files or copy the ones passed X * First find if there are any. X */ X s = Filter_out? Filter_out : Read_stdin; X if( s ){ X Get_stat( SD, s, &f_stat ); X j = (f_stat.st_size + 1023) / 1024; X for( c = 0; c == 0 || c < Copies; ++c ){ X Entry( Format, s, cfp ); X jobsize += j; X if( MX && jobsize > MX ){ X Diemsg( "job too large. split up" ); X } X Entry( 'U', s, cfp ); X } X } else { X /* X * we create an entry for each file in the list X */ X for( i = 0; i < Parmcount; ++i ){ X if( Parms[i].str ){ X /* X * repeat the check for printability X */ X if( (fd = Is_printable( Parms[i].str, &f_stat )) < 0 ){ X fatal(XLOG_CRIT, "Make_job: file %s become bad, %s@%s", X Parms[i].str, Person, Host ); X } X if( Use_links ){ X /* X * try to make a symbolic link to the file X */ X s = Make_link(Parms[i].str, &c_stat ); X } else { X /* X * make a copy in the spool directory X */ X s = Copy_file( fd, Parms[i].str, &c_stat); X } X (void)strcpy(Parms[i].filename, s); X (void)close(fd); X if( f_stat.st_size != c_stat.st_size ){ X fatal(XLOG_CRIT,"Make_job: file %s changed, %s@%s", X Parms[i].str, Person, Host ); X } X Parms[i].size = (f_stat.st_size + 1023)/1024; X if(Debug>4)log(XLOG_DEBUG,"Make_job: %s -> %s, %d", X Parms[i].str, Parms[i].filename, Parms[i].size ); X } X } X for( c = 0; c == 0 || c < Copies; ++c ){ X for( i = 0; i < Parmcount; ++i ){ X if( Parms[i].str ){ X Entry( Format, Parms[i].filename, cfp ); X jobsize += Parms[i].size; X if( MX && jobsize > MX ){ X Diemsg( "job too large (over %ldK). split up", jobsize); X } X } X } X } X /* X * Remove the file after we have used it X */ X for( i = 0; i < Parmcount; ++i ){ X if( Parms[i].str ){ X Entry( 'U', Parms[i].filename, cfp ); X if( Remove && Use_links == 0 ){ X /* set the EUID to user */ X Set_uid( getuid() ); X if( unlink( Parms[i].str ) < 0 ){ X Warnmsg( "could not remove %s- %s",Parms[i].str, X Errormsg(errno) ); X } X Clear_uid(); X } X } X } X } X /* X * flush the control file and rename it X */ X if( fflush( cfp ) == EOF ){ X logerr_die(XLOG_INFO, "cannot flush %s", cf ); X } X if( fclose( cfp ) == EOF ){ X logerr_die(XLOG_INFO, "cannot close %s", cf ); X } X Rename_cf(cf); X} X X/*************************************************************************** X * Entry( char c; char *cp; FILE *fp ) X * Prints a line out in the control file X ***************************************************************************/ XEntry( c, cp, fp ) X int c; X char *cp; X FILE *fp; X{ X int d; X X d = 0; X if(Debug>4)log(XLOG_DEBUG,"Entry: %c '%s'", c, cp ); X if( strlen( cp ) > MAXPARMLEN ){ X d = cp[MAXPARMLEN]; X cp[MAXPARMLEN] = 0; X } X if( fprintf( fp, "%c%s\n", c, cp ) == EOF ){ X logerr_die( XLOG_INFO, "error while writing control file" ); X } X if( d ){ X cp[MAXPARMLEN] = d; X } X} X X X/*************************************************************************** X * Make_link( char *target, struct stat *statb ) X * makes a link to the target, and puts out entry X ***************************************************************************/ static char * Make_link( target, statb ) X char *target; X struct stat *statb; X{ X#ifdef NOSYMLINK X fatal( XLOG_INFO, "no symbolic links allowed" ); X#else NOSYMLINK X char *lf; /* link file */ X char buf[MAXPATHLEN]; X uid_t ruid, euid; X X euid = geteuid(); X /* X * get temp file name X */ X lf = Get_tmp_data(); X (void)sprintf(buf,"%s/%s", SD, lf ); X /* X * generate absolute path name X */ X target = Full_path( target ); X if(Debug>3)log(XLOG_DEBUG,"Make_link: from %s to %s", buf, target ); X Set_daemon(); X if( symlink( target, buf ) < 0 ){ X logerr_die( XLOG_INFO, "Make_link: symbolic link from %s to %s failed", X buf, target ); X } X if( stat( target, statb ) < 0 ){ X logerr_die( XLOG_INFO, "Make_link: stat failed '%s'", target ); X } X Clear_uid(); X return( lf ); X#endif NOSYMLINK X} X X X/*************************************************************************** X * Get_stat( char * dir, char *file , struct stat *statb) X * stat the file in the specified directory X ***************************************************************************/ X Get_stat(dir, file, statb ) X char *dir; X char *file; X struct stat *statb; /* status buffer */ X{ X static char buf[BUFSIZ]; /* for holding the pathname */ X X if( dir && *dir ){ X (void)sprintf( buf, "%s/%s", dir, file ); X } else { X (void)strcpy( buf, file ); X } X if( stat( buf, statb ) < 0 ){ X logerr_die( XLOG_INFO, "Get_stat: cannot stat %s", buf ); X } X if(Debug>5)log(XLOG_DEBUG,"Get_stat: %s is %ld", buf, statb->st_size ); X} X X/*************************************************************************** X * Get_home() X * get the current directory X ***************************************************************************/ static char dir[MAXPATHLEN]; X char * Get_home() X{ X /* X * get current working directory X */ X if( dir[0] == 0 ){ X Set_uid( getuid() ); X if( getwd(dir) == 0 ){ X logerr_die(XLOG_INFO, "Get_home: getwd() failed" ); X } X Clear_uid(); X } X return( dir ); X} X/*************************************************************************** X * Full_path( char *file ) X * return the full path name X ***************************************************************************/ X static char full[MAXPATHLEN]; char * XFull_path( file ) X char *file; X{ X if( file[0] == '/' ){ X (void)strcpy( full, file ); X } else { X (void)sprintf( full, "%s/%s", Get_home(), file ); X } X return( full ); X} END_OF_FILE if test 9221 -ne `wc -c <'src/lpr_job.c'`; then echo shar: \"'src/lpr_job.c'\" unpacked with wrong size! fi # end of 'src/lpr_job.c' fi echo shar: End of archive 6 \(of 16\). cp /dev/null ark6isdone 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 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.