displayq.c revision 1553
159769Sgrog/*
259769Sgrog * Copyright (c) 1983, 1993
324424Swosch *	The Regents of the University of California.  All rights reserved.
424424Swosch *
524424Swosch * Redistribution and use in source and binary forms, with or without
624424Swosch * modification, are permitted provided that the following conditions
724424Swosch * are met:
824424Swosch * 1. Redistributions of source code must retain the above copyright
924424Swosch *    notice, this list of conditions and the following disclaimer.
1024424Swosch * 2. Redistributions in binary form must reproduce the above copyright
1124424Swosch *    notice, this list of conditions and the following disclaimer in the
1224424Swosch *    documentation and/or other materials provided with the distribution.
1324424Swosch * 3. All advertising materials mentioning features or use of this software
1424424Swosch *    must display the following acknowledgement:
1542704Swosch *	This product includes software developed by the University of
1642704Swosch *	California, Berkeley and its contributors.
1742704Swosch * 4. Neither the name of the University nor the names of its contributors
1824424Swosch *    may be used to endorse or promote products derived from this software
1942704Swosch *    without specific prior written permission.
2042704Swosch *
2142704Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2242704Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2342704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2442704Swosch * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2542704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2642704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2742704Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2842704Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2942704Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3059769Sgrog * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3159769Sgrog * SUCH DAMAGE.
3259769Sgrog */
3359769Sgrog
3459769Sgrog#ifndef lint
3559769Sgrogstatic char sccsid[] = "@(#)displayq.c	8.1 (Berkeley) 6/6/93";
3659769Sgrog#endif /* not lint */
3759769Sgrog
3859769Sgrog#include <sys/param.h>
3924424Swosch#include <sys/stat.h>
4042704Swosch
4124424Swosch#include <signal.h>
4242704Swosch#include <fcntl.h>
4324424Swosch#include <dirent.h>
4442704Swosch#include <unistd.h>
4524424Swosch#include <stdio.h>
4624424Swosch#include <stdlib.h>
4724424Swosch#include <string.h>
4842704Swosch#include <ctype.h>
4925031Swosch#include "lp.h"
5059156Swosch#include "lp.local.h"
5125031Swosch#include "pathnames.h"
5225031Swosch
5324424Swosch/*
5424424Swosch * Routines to display the state of the queue.
5524424Swosch */
5624424Swosch#define JOBCOL	40		/* column for job # in -l format */
5771231Sitojun#define OWNCOL	7		/* start of Owner column in normal */
5824424Swosch#define SIZCOL	62		/* start of Size column in normal */
5971231Sitojun
6025031Swosch/*
6171231Sitojun * Stuff for handling job specifications
6224424Swosch */
6325031Swoschextern int	requ[];		/* job number of spool entries */
6425031Swoschextern int	requests;	/* # of spool requests */
6571231Sitojunextern char    *user[];	        /* users to process */
6625031Swoschextern int	users;		/* # of users in user array */
6771231Sitojun
6870110Swoschstatic int	col;		/* column on screen */
6970110Swoschstatic char	current[40];	/* current file being printed */
7070110Swoschstatic char	file[132];	/* print file name */
7170110Swoschstatic int	first;		/* first file in ``files'' column? */
7270110Swoschstatic int	garbage;	/* # of garbage cf files */
7370110Swoschstatic int	lflag;		/* long output option */
7470110Swoschstatic int	rank;		/* order to be printed (-1=none, 0=active) */
7570110Swoschstatic long	totsize;	/* total print job size in bytes */
7670110Swosch
7770110Swoschstatic char	*head0 = "Rank   Owner      Job  Files";
7870110Swoschstatic char	*head1 = "Total Size\n";
7980675Sasmodai
8080675Sasmodai/*
8180675Sasmodai * Display the current state of the queue. Format = 1 if long format.
8280675Sasmodai */
8380675Sasmodaivoid
8480675Sasmodaidisplayq(format)
8580675Sasmodai	int format;
8680675Sasmodai{
8780675Sasmodai	register struct queue *q;
8880675Sasmodai	register int i, nitems, fd;
8980675Sasmodai	register char	*cp;
9080675Sasmodai	struct queue **queue;
9180675Sasmodai	struct stat statb;
9280675Sasmodai	FILE *fp;
9380675Sasmodai
9480675Sasmodai	lflag = format;
9580675Sasmodai	totsize = 0;
9680675Sasmodai	rank = -1;
9780675Sasmodai	if ((i = cgetent(&bp, printcapdb, printer)) == -2)
9880675Sasmodai		fatal("can't open printer description file");
9980675Sasmodai	else if (i == -1)
10080675Sasmodai		fatal("unknown printer");
10180675Sasmodai	else if (i == -3)
10280675Sasmodai		fatal("potential reference loop detected in printcap file");
10380675Sasmodai	if (cgetstr(bp, "lp", &LP) < 0)
10480675Sasmodai		LP = _PATH_DEFDEVLP;
10580675Sasmodai	if (cgetstr(bp, "rp", &RP) < 0)
10680675Sasmodai		RP = DEFLP;
10780675Sasmodai	if (cgetstr(bp, "sd", &SD) < 0)
10880675Sasmodai		SD = _PATH_DEFSPOOL;
10980675Sasmodai	if (cgetstr(bp,"lo", &LO) < 0)
11080675Sasmodai		LO = DEFLOCK;
11180675Sasmodai	if (cgetstr(bp, "st", &ST) < 0)
11280675Sasmodai		ST = DEFSTAT;
11380675Sasmodai	cgetstr(bp, "rm", &RM);
11480675Sasmodai	if (cp = checkremote())
11580675Sasmodai		printf("Warning: %s\n", cp);
11680675Sasmodai
11780675Sasmodai	/*
11880675Sasmodai	 * Print out local queue
11980675Sasmodai	 * Find all the control files in the spooling directory
12080675Sasmodai	 */
12180675Sasmodai	if (chdir(SD) < 0)
12280675Sasmodai		fatal("cannot chdir to spooling directory");
12380675Sasmodai	if ((nitems = getq(&queue)) < 0)
12480675Sasmodai		fatal("cannot examine spooling area\n");
12580675Sasmodai	if (stat(LO, &statb) >= 0) {
12680675Sasmodai		if (statb.st_mode & 0100) {
12780675Sasmodai			if (sendtorem)
12880675Sasmodai				printf("%s: ", host);
12980675Sasmodai			printf("Warning: %s is down: ", printer);
13080675Sasmodai			fd = open(ST, O_RDONLY);
13180675Sasmodai			if (fd >= 0) {
13280675Sasmodai				(void) flock(fd, LOCK_SH);
13380675Sasmodai				while ((i = read(fd, line, sizeof(line))) > 0)
13480675Sasmodai					(void) fwrite(line, 1, i, stdout);
13580675Sasmodai				(void) close(fd);	/* unlocks as well */
13680675Sasmodai			} else
13780675Sasmodai				putchar('\n');
138101401Swosch		}
13980675Sasmodai		if (statb.st_mode & 010) {
14087200Swosch			if (sendtorem)
14187200Swosch				printf("%s: ", host);
14287200Swosch			printf("Warning: %s queue is turned off\n", printer);
14380675Sasmodai		}
144104772Smaxim	}
145104772Smaxim
146104772Smaxim	if (nitems) {
147104772Smaxim		fp = fopen(LO, "r");
148104781Sjhb		if (fp == NULL)
149104781Sjhb			warn();
150104781Sjhb		else {
151104781Sjhb			/* get daemon pid */
152104781Sjhb			cp = current;
153104781Sjhb			while ((*cp = getc(fp)) != EOF && *cp != '\n')
154104781Sjhb				cp++;
155113054Smurray			*cp = '\0';
156113054Smurray			i = atoi(current);
157113054Smurray			if (i <= 0 || kill(i, 0) < 0)
158114211Swosch				warn();
159114211Swosch			else {
160114211Swosch				/* read current file name */
161114211Swosch				cp = current;
162114211Swosch				while ((*cp = getc(fp)) != EOF && *cp != '\n')
163111949Swosch					cp++;
164111949Swosch				*cp = '\0';
16580675Sasmodai				/*
16680675Sasmodai				 * Print the status file.
167104781Sjhb				 */
16824424Swosch				if (sendtorem)
16924424Swosch					printf("%s: ", host);
17024424Swosch				fd = open(ST, O_RDONLY);
17124424Swosch				if (fd >= 0) {
17269277Sasmodai					(void) flock(fd, LOCK_SH);
17369277Sasmodai					while ((i = read(fd, line, sizeof(line))) > 0)
17424424Swosch						(void) fwrite(line, 1, i, stdout);
17525031Swosch					(void) close(fd);	/* unlocks as well */
17625031Swosch				} else
17725031Swosch					putchar('\n');
17880675Sasmodai			}
179104782Sjhb			(void) fclose(fp);
18025031Swosch		}
181104782Sjhb		/*
182104782Sjhb		 * Now, examine the control files and print out the jobs to
183104782Sjhb		 * be done for each user.
184104797Sjhb		 */
185104797Sjhb		if (!lflag)
18625031Swosch			header();
18725031Swosch		for (i = 0; i < nitems; i++) {
18825031Swosch			q = queue[i];
18945349Swosch			inform(q->q_name);
19045349Swosch			free(q);
191104782Sjhb		}
192104782Sjhb		free(queue);
193104782Sjhb	}
194104782Sjhb	if (!sendtorem) {
19542704Swosch		if (nitems == 0)
19625031Swosch			puts("no entries");
19724424Swosch		return;
19859769Sgrog	}
19925031Swosch
20025031Swosch	/*
20125031Swosch	 * Print foreign queue
20225031Swosch	 * Note that a file in transit may show up in either queue.
20359769Sgrog	 */
20425031Swosch	if (nitems)
20525031Swosch		putchar('\n');
20625031Swosch	(void) sprintf(line, "%c%s", format + '\3', RP);
20725031Swosch	cp = line;
20824424Swosch	for (i = 0; i < requests; i++) {
20925031Swosch		cp += strlen(cp);
21025031Swosch		(void) sprintf(cp, " %d", requ[i]);
21125031Swosch	}
21225031Swosch	for (i = 0; i < users; i++) {
21325031Swosch		cp += strlen(cp);
21459769Sgrog		*cp++ = ' ';
21559769Sgrog		(void) strcpy(cp, user[i]);
21642704Swosch	}
21742704Swosch	strcat(line, "\n");
21842704Swosch	fd = getport(RM);
21970110Swosch	if (fd < 0) {
22042704Swosch		if (from != host)
22142704Swosch			printf("%s: ", host);
22225031Swosch		printf("connection to %s is down\n", RM);
22325031Swosch	}
22424424Swosch	else {
22525031Swosch		i = strlen(line);
22625031Swosch		if (write(fd, line, i) != i)
22725031Swosch			fatal("Lost connection");
22825031Swosch		while ((i = read(fd, line, sizeof(line))) > 0)
22925031Swosch			(void) fwrite(line, 1, i, stdout);
23025031Swosch		(void) close(fd);
23125031Swosch	}
23225031Swosch}
23325031Swosch
23424424Swosch/*
23525031Swosch * Print a warning message if there is no daemon present.
23625031Swosch */
23725031Swoschvoid
23825031Swoschwarn()
23925031Swosch{
24025031Swosch	if (sendtorem)
24125031Swosch		printf("\n%s: ", host);
24225031Swosch	puts("Warning: no daemon present");
24359156Swosch	current[0] = '\0';
24425031Swosch}
24525031Swosch
24625031Swosch/*
24725031Swosch * Print the header for the short listing format
24825031Swosch */
24925031Swoschvoid
25089981Sjoeheader()
25125031Swosch{
25225031Swosch	printf(head0);
25325031Swosch	col = strlen(head0)+1;
25424424Swosch	blankfill(SIZCOL);
25525031Swosch	printf(head1);
25625031Swosch}
25789981Sjoe
25825031Swoschvoid
25989981Sjoeinform(cf)
26089981Sjoe	char *cf;
26125031Swosch{
26289981Sjoe	register int j;
26389981Sjoe	FILE *cfp;
26489981Sjoe
26570110Swosch	/*
26671231Sitojun	 * There's a chance the control file has gone away
26770110Swosch	 * in the meantime; if this is the case just keep going
26825031Swosch	 */
26971231Sitojun	if ((cfp = fopen(cf, "r")) == NULL)
27071231Sitojun		return;
27169278Sasmodai
27225031Swosch	if (rank < 0)
27371231Sitojun		rank = 0;
27470110Swosch	if (sendtorem || garbage || strcmp(cf, current))
27571231Sitojun		rank++;
27670110Swosch	j = 0;
27770110Swosch	while (getline(cfp)) {
27871231Sitojun		switch (line[0]) {
27970110Swosch		case 'P': /* Was this file specified in the user's list? */
28057000Swosch			if (!inlist(line+1, cf)) {
28125031Swosch				fclose(cfp);
28245349Swosch				return;
28378270Snik			}
28471231Sitojun			if (lflag) {
28525031Swosch				printf("\n%s: ", line+1);
28638440Sjkh				col = strlen(line+1) + 2;
28738440Sjkh				prank(rank);
28849392Swosch				blankfill(JOBCOL);
28957000Swosch				printf(" [job %s]\n", cf+3);
29038440Sjkh			} else {
29138440Sjkh				col = 0;
29270110Swosch				prank(rank);
29369278Sasmodai				blankfill(OWNCOL);
29470110Swosch				printf("%-10s %-3d  ", line+1, atoi(cf+3));
29525031Swosch				col += 16;
29625031Swosch				first = 1;
29769278Sasmodai			}
29845349Swosch			continue;
29970110Swosch		default: /* some format specifer and file name? */
30069278Sasmodai			if (line[0] < 'a' || line[0] > 'z')
30145349Swosch				continue;
30245349Swosch			if (j == 0 || strcmp(file, line+1) != 0)
30369278Sasmodai				(void) strcpy(file, line+1);
30469278Sasmodai			j++;
30580675Sasmodai			continue;
30669278Sasmodai		case 'N':
30770110Swosch			show(line+1, file, j);
30869278Sasmodai			file[0] = '\0';
30969278Sasmodai			j = 0;
31069278Sasmodai		}
31157000Swosch	}
31245349Swosch	fclose(cfp);
31369277Sasmodai	if (!lflag) {
31445349Swosch		blankfill(SIZCOL);
31566542Sitojun		printf("%ld bytes\n", totsize);
31669277Sasmodai		totsize = 0;
31757000Swosch	}
31870110Swosch}
31945349Swosch
32057000Swoschint
32169277Sasmodaiinlist(name, file)
32270110Swosch	char *name, *file;
32370110Swosch{
32442589Swosch	register int *r, n;
32570110Swosch	register char **u, *cp;
32670110Swosch
32746321Swosch	if (users == 0 && requests == 0)
32845349Swosch		return(1);
32945349Swosch	/*
33057000Swosch	 * Check to see if it's in the user list
33146318Swosch	 */
33270110Swosch	for (u = user; u < &user[users]; u++)
33356406Swosch		if (!strcmp(*u, name))
33455389Sbillf			return(1);
33555389Sbillf	/*
33657000Swosch	 * Check the request list
33755389Sbillf	 */
33855389Sbillf	for (n = 0, cp = file+3; isdigit(*cp); )
33955389Sbillf		n = n * 10 + (*cp++ - '0');
34070110Swosch	for (r = requ; r < &requ[requests]; r++)
34158448Swosch		if (*r == n && !strcmp(cp, from))
34258448Swosch			return(1);
34365412Swosch	return(0);
34464612Salex}
34564612Salex
34665411Swoschvoid
34765974Swoschshow(nfile, file, copies)
34869277Sasmodai	register char *nfile, *file;
34969277Sasmodai	int copies;
35070119Swosch{
35169277Sasmodai	if (strcmp(nfile, " ") == 0)
35270111Swosch		nfile = "(standard input)";
35380675Sasmodai	if (lflag)
35475833Swosch		ldump(nfile, file, copies);
35578867Sitojun	else
35679603Sitojun		dump(nfile, file, copies);
35784087Swosch}
35883686Sobrien
359104797Sjhb/*
36087201Swosch * Fill the line with blanks to the specified column
36192013Swosch */
362104772Smaximvoid
363101331Swoschblankfill(n)
364101331Swosch	register int n;
365104797Sjhb{
366104781Sjhb	while (col++ < n)
367104781Sjhb		putchar(' ');
368104781Sjhb}
369104659Smurray
370106406Smaxim/*
371111949Swosch * Give the abbreviated dump of the file names
372111949Swosch */
373111949Swoschvoid
374113054Smurraydump(nfile, file, copies)
375114211Swosch	char *nfile, *file;
37624424Swosch	int copies;
377111949Swosch{
37824424Swosch	register short n, fill;
37924424Swosch	struct stat lbuf;
38024424Swosch
38124424Swosch	/*
38224424Swosch	 * Print as many files as will fit
38324424Swosch	 *  (leaving room for the total size)
38424424Swosch	 */
38524424Swosch	 fill = first ? 0 : 2;	/* fill space for ``, '' */
38624424Swosch	 if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
38724424Swosch		if (col < SIZCOL) {
38824424Swosch			printf(" ..."), col += 4;
38924424Swosch			blankfill(SIZCOL);
39024424Swosch		}
39124424Swosch	} else {
39225031Swosch		if (first)
39325031Swosch			first = 0;
39424424Swosch		else
39524424Swosch			printf(", ");
39624424Swosch		printf("%s", nfile);
39724424Swosch		col += n+fill;
39859769Sgrog	}
39979514Sitojun	if (*file && !stat(file, &lbuf))
40024424Swosch		totsize += copies * lbuf.st_size;
40125031Swosch}
40225031Swosch
40325031Swosch/*
40425031Swosch * Print the long info about the file
40559769Sgrog */
40625031Swoschvoid
40731658Swoschldump(nfile, file, copies)
40879514Sitojun	char *nfile, *file;
40931658Swosch	int copies;
41059769Sgrog{
41179514Sitojun	struct stat lbuf;
41259769Sgrog
41365415Swosch	putchar('\t');
414104786Sjhb	if (copies > 1)
41565415Swosch		printf("%-2d copies of %-19s", copies, nfile);
41675834Swosch	else
41779514Sitojun		printf("%-32s", nfile);
41875834Swosch	if (*file && !stat(file, &lbuf))
41975834Swosch		printf(" %qd bytes", lbuf.st_size);
42075834Swosch	else
42125031Swosch		printf(" ??? bytes");
42225031Swosch	putchar('\n');
42325031Swosch}
42459769Sgrog
42525031Swosch/*
42625031Swosch * Print the job's rank in the queue,
42731658Swosch *   update col for screen management
42825031Swosch */
42924424Swoschvoid
43072877Swoschprank(n)
43167388Swosch	int n;
43242589Swosch{
43350970Speter	char rline[100];
434	static char *r[] = {
435		"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
436	};
437
438	if (n == 0) {
439		printf("active");
440		col += 6;
441		return;
442	}
443	if ((n/10)%10 == 1)
444		(void)snprintf(rline, sizeof(rline), "%dth", n);
445	else
446		(void)snprintf(rline, sizeof(rline), "%d%s", n, r[n%10]);
447	col += strlen(rline);
448	printf("%s", rline);
449}
450