Home | History | Annotate | Line # | Download | only in common_source
displayq.c revision 1.3
      1 /*
      2  * Copyright (c) 1983 Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 /*static char sccsid[] = "from: @(#)displayq.c	5.13 (Berkeley) 6/1/90";*/
     36 static char rcsid[] = "$Id: displayq.c,v 1.3 1994/03/27 09:15:15 cgd Exp $";
     37 #endif /* not lint */
     38 
     39 /*
     40  * Routines to display the state of the queue.
     41  */
     42 
     43 #include "lp.h"
     44 #include "pathnames.h"
     45 
     46 #define JOBCOL	40		/* column for job # in -l format */
     47 #define OWNCOL	7		/* start of Owner column in normal */
     48 #define SIZCOL	62		/* start of Size column in normal */
     49 
     50 /*
     51  * Stuff for handling job specifications
     52  */
     53 extern char	*user[];	/* users to process */
     54 extern int	users;		/* # of users in user array */
     55 extern int	requ[];		/* job number of spool entries */
     56 extern int	requests;	/* # of spool requests */
     57 
     58 int	lflag;		/* long output option */
     59 char	current[40];	/* current file being printed */
     60 int	garbage;	/* # of garbage cf files */
     61 int	rank;		/* order to be printed (-1=none, 0=active) */
     62 long	totsize;	/* total print job size in bytes */
     63 int	first;		/* first file in ``files'' column? */
     64 int	col;		/* column on screen */
     65 char	file[132];	/* print file name */
     66 
     67 char	*head0 = "Rank   Owner      Job  Files";
     68 char	*head1 = "Total Size\n";
     69 
     70 /*
     71  * Display the current state of the queue. Format = 1 if long format.
     72  */
     73 displayq(format)
     74 	int format;
     75 {
     76 	register struct queue *q;
     77 	register int i, nitems, fd;
     78 	register char	*cp;
     79 	struct queue **queue;
     80 	struct stat statb;
     81 	FILE *fp;
     82 	char c;
     83 
     84 	lflag = format;
     85 	totsize = 0;
     86 	rank = -1;
     87 
     88 	if ((i = pgetent(line, printer)) < 0)
     89 		fatal("cannot open printer description file");
     90 	else if (i == 0)
     91 		fatal("unknown printer");
     92 	if ((LP = pgetstr("lp", &bp)) == NULL)
     93 		LP = _PATH_DEFDEVLP;
     94 	if ((RP = pgetstr("rp", &bp)) == NULL)
     95 		RP = DEFLP;
     96 	if ((SD = pgetstr("sd", &bp)) == NULL)
     97 		SD = _PATH_DEFSPOOL;
     98 	if ((LO = pgetstr("lo", &bp)) == NULL)
     99 		LO = DEFLOCK;
    100 	if ((ST = pgetstr("st", &bp)) == NULL)
    101 		ST = DEFSTAT;
    102 	RM = pgetstr("rm", &bp);
    103 	if (cp = checkremote())
    104 		printf("Warning: %s\n", cp);
    105 
    106 	/*
    107 	 * Print out local queue
    108 	 * Find all the control files in the spooling directory
    109 	 */
    110 	if (chdir(SD) < 0)
    111 		fatal("cannot chdir to spooling directory");
    112 	if ((nitems = getq(&queue)) < 0)
    113 		fatal("cannot examine spooling area\n");
    114 	if (stat(LO, &statb) >= 0) {
    115 		if (statb.st_mode & 0100) {
    116 			if (sendtorem)
    117 				printf("%s: ", host);
    118 			printf("Warning: %s is down: ", printer);
    119 			fd = open(ST, O_RDONLY);
    120 			if (fd >= 0) {
    121 				(void) flock(fd, LOCK_SH);
    122 				while ((i = read(fd, line, sizeof(line))) > 0)
    123 					(void) fwrite(line, 1, i, stdout);
    124 				(void) close(fd);	/* unlocks as well */
    125 			} else
    126 				putchar('\n');
    127 		}
    128 		if (statb.st_mode & 010) {
    129 			if (sendtorem)
    130 				printf("%s: ", host);
    131 			printf("Warning: %s queue is turned off\n", printer);
    132 		}
    133 	}
    134 
    135 	if (nitems) {
    136 		fp = fopen(LO, "r");
    137 		if (fp == NULL)
    138 			warn();
    139 		else {
    140 			/* get daemon pid */
    141 			cp = current;
    142 			while ((*cp = getc(fp)) != EOF && *cp != '\n')
    143 				cp++;
    144 			*cp = '\0';
    145 			i = atoi(current);
    146 			if (i <= 0 || kill(i, 0) < 0)
    147 				warn();
    148 			else {
    149 				/* read current file name */
    150 				cp = current;
    151 				while ((*cp = getc(fp)) != EOF && *cp != '\n')
    152 					cp++;
    153 				*cp = '\0';
    154 				/*
    155 				 * Print the status file.
    156 				 */
    157 				if (sendtorem)
    158 					printf("%s: ", host);
    159 				fd = open(ST, O_RDONLY);
    160 				if (fd >= 0) {
    161 					(void) flock(fd, LOCK_SH);
    162 					while ((i = read(fd, line, sizeof(line))) > 0)
    163 						(void) fwrite(line, 1, i, stdout);
    164 					(void) close(fd);	/* unlocks as well */
    165 				} else
    166 					putchar('\n');
    167 			}
    168 			(void) fclose(fp);
    169 		}
    170 		/*
    171 		 * Now, examine the control files and print out the jobs to
    172 		 * be done for each user.
    173 		 */
    174 		if (!lflag)
    175 			header();
    176 		for (i = 0; i < nitems; i++) {
    177 			q = queue[i];
    178 			inform(q->q_name);
    179 			free(q);
    180 		}
    181 		free(queue);
    182 	}
    183 	if (!sendtorem) {
    184 		if (nitems == 0)
    185 			puts("no entries");
    186 		return;
    187 	}
    188 
    189 	/*
    190 	 * Print foreign queue
    191 	 * Note that a file in transit may show up in either queue.
    192 	 */
    193 	if (nitems)
    194 		putchar('\n');
    195 	(void) sprintf(line, "%c%s", format + '\3', RP);
    196 	cp = line;
    197 	for (i = 0; i < requests; i++) {
    198 		cp += strlen(cp);
    199 		(void) sprintf(cp, " %d", requ[i]);
    200 	}
    201 	for (i = 0; i < users; i++) {
    202 		cp += strlen(cp);
    203 		*cp++ = ' ';
    204 		(void) strcpy(cp, user[i]);
    205 	}
    206 	strcat(line, "\n");
    207 	fd = getport(RM);
    208 	if (fd < 0) {
    209 		if (from != host)
    210 			printf("%s: ", host);
    211 		printf("connection to %s is down\n", RM);
    212 	}
    213 	else {
    214 		i = strlen(line);
    215 		if (write(fd, line, i) != i)
    216 			fatal("Lost connection");
    217 		while ((i = read(fd, line, sizeof(line))) > 0)
    218 			(void) fwrite(line, 1, i, stdout);
    219 		(void) close(fd);
    220 	}
    221 }
    222 
    223 /*
    224  * Print a warning message if there is no daemon present.
    225  */
    226 warn()
    227 {
    228 	if (sendtorem)
    229 		printf("\n%s: ", host);
    230 	puts("Warning: no daemon present");
    231 	current[0] = '\0';
    232 }
    233 
    234 /*
    235  * Print the header for the short listing format
    236  */
    237 header()
    238 {
    239 	printf(head0);
    240 	col = strlen(head0)+1;
    241 	blankfill(SIZCOL);
    242 	printf(head1);
    243 }
    244 
    245 inform(cf)
    246 	char *cf;
    247 {
    248 	register int j, k;
    249 	register char *cp;
    250 	FILE *cfp;
    251 
    252 	/*
    253 	 * There's a chance the control file has gone away
    254 	 * in the meantime; if this is the case just keep going
    255 	 */
    256 	if ((cfp = fopen(cf, "r")) == NULL)
    257 		return;
    258 
    259 	if (rank < 0)
    260 		rank = 0;
    261 	if (sendtorem || garbage || strcmp(cf, current))
    262 		rank++;
    263 	j = 0;
    264 	while (getline(cfp)) {
    265 		switch (line[0]) {
    266 		case 'P': /* Was this file specified in the user's list? */
    267 			if (!inlist(line+1, cf)) {
    268 				fclose(cfp);
    269 				return;
    270 			}
    271 			if (lflag) {
    272 				printf("\n%s: ", line+1);
    273 				col = strlen(line+1) + 2;
    274 				prank(rank);
    275 				blankfill(JOBCOL);
    276 				printf(" [job %s]\n", cf+3);
    277 			} else {
    278 				col = 0;
    279 				prank(rank);
    280 				blankfill(OWNCOL);
    281 				printf("%-10s %-3d  ", line+1, atoi(cf+3));
    282 				col += 16;
    283 				first = 1;
    284 			}
    285 			continue;
    286 		default: /* some format specifer and file name? */
    287 			if (line[0] < 'a' || line[0] > 'z')
    288 				continue;
    289 			if (j == 0 || strcmp(file, line+1) != 0)
    290 				(void) strcpy(file, line+1);
    291 			j++;
    292 			continue;
    293 		case 'N':
    294 			show(line+1, file, j);
    295 			file[0] = '\0';
    296 			j = 0;
    297 		}
    298 	}
    299 	fclose(cfp);
    300 	if (!lflag) {
    301 		blankfill(SIZCOL);
    302 		printf("%ld bytes\n", totsize);
    303 		totsize = 0;
    304 	}
    305 }
    306 
    307 inlist(name, file)
    308 	char *name, *file;
    309 {
    310 	register int *r, n;
    311 	register char **u, *cp;
    312 
    313 	if (users == 0 && requests == 0)
    314 		return(1);
    315 	/*
    316 	 * Check to see if it's in the user list
    317 	 */
    318 	for (u = user; u < &user[users]; u++)
    319 		if (!strcmp(*u, name))
    320 			return(1);
    321 	/*
    322 	 * Check the request list
    323 	 */
    324 	for (n = 0, cp = file+3; isdigit(*cp); )
    325 		n = n * 10 + (*cp++ - '0');
    326 	for (r = requ; r < &requ[requests]; r++)
    327 		if (*r == n && !strcmp(cp, from))
    328 			return(1);
    329 	return(0);
    330 }
    331 
    332 show(nfile, file, copies)
    333 	register char *nfile, *file;
    334 {
    335 	if (strcmp(nfile, " ") == 0)
    336 		nfile = "(standard input)";
    337 	if (lflag)
    338 		ldump(nfile, file, copies);
    339 	else
    340 		dump(nfile, file, copies);
    341 }
    342 
    343 /*
    344  * Fill the line with blanks to the specified column
    345  */
    346 blankfill(n)
    347 	register int n;
    348 {
    349 	while (col++ < n)
    350 		putchar(' ');
    351 }
    352 
    353 /*
    354  * Give the abbreviated dump of the file names
    355  */
    356 dump(nfile, file, copies)
    357 	char *nfile, *file;
    358 {
    359 	register short n, fill;
    360 	struct stat lbuf;
    361 
    362 	/*
    363 	 * Print as many files as will fit
    364 	 *  (leaving room for the total size)
    365 	 */
    366 	 fill = first ? 0 : 2;	/* fill space for ``, '' */
    367 	 if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
    368 		if (col < SIZCOL) {
    369 			printf(" ..."), col += 4;
    370 			blankfill(SIZCOL);
    371 		}
    372 	} else {
    373 		if (first)
    374 			first = 0;
    375 		else
    376 			printf(", ");
    377 		printf("%s", nfile);
    378 		col += n+fill;
    379 	}
    380 	if (*file && !stat(file, &lbuf))
    381 		totsize += copies * lbuf.st_size;
    382 }
    383 
    384 /*
    385  * Print the long info about the file
    386  */
    387 ldump(nfile, file, copies)
    388 	char *nfile, *file;
    389 {
    390 	struct stat lbuf;
    391 
    392 	putchar('\t');
    393 	if (copies > 1)
    394 		printf("%-2d copies of %-19s", copies, nfile);
    395 	else
    396 		printf("%-32s", nfile);
    397 	if (*file && !stat(file, &lbuf))
    398 		printf(" %qd bytes", lbuf.st_size);
    399 	else
    400 		printf(" ??? bytes");
    401 	putchar('\n');
    402 }
    403 
    404 /*
    405  * Print the job's rank in the queue,
    406  *   update col for screen management
    407  */
    408 prank(n)
    409 {
    410 	char line[100];
    411 	static char *r[] = {
    412 		"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
    413 	};
    414 
    415 	if (n == 0) {
    416 		printf("active");
    417 		col += 6;
    418 		return;
    419 	}
    420 	if ((n/10)%10 == 1)
    421 		(void) sprintf(line, "%dth", n);
    422 	else
    423 		(void) sprintf(line, "%d%s", n, r[n%10]);
    424 	col += strlen(line);
    425 	printf("%s", line);
    426 }
    427