Add copyright
[unix-history] / usr / src / usr.sbin / lpr / common_source / displayq.c
CommitLineData
d0aeaf5a
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
5f84f8f0 7#ifndef lint
d0aeaf5a
DF
8static char sccsid[] = "@(#)displayq.c 5.1 (Berkeley) %G%";
9#endif not lint
5f84f8f0 10
41d14893
RC
11/*
12 * Routines to display the state of the queue.
13 */
14
15#include "lp.h"
16
c6d1c018
RC
17#define JOBCOL 40 /* column for job # in -l format */
18#define OWNCOL 7 /* start of Owner column in normal */
19#define SIZCOL 62 /* start of Size column in normal */
41d14893
RC
20
21/*
22 * Stuff for handling job specifications
23 */
24extern char *user[]; /* users to process */
25extern int users; /* # of users in user array */
26extern int requ[]; /* job number of spool entries */
27extern int requests; /* # of spool requests */
28
3d3c9f9f
RC
29int lflag; /* long output option */
30char current[40]; /* current file being printed */
31int garbage; /* # of garbage cf files */
32int rank; /* order to be printed (-1=none, 0=active) */
33long totsize; /* total print job size in bytes */
34int first; /* first file in ``files'' column? */
35int col; /* column on screen */
36int sendtorem; /* are we sending to a remote? */
37char file[132]; /* print file name */
41d14893 38
3d3c9f9f
RC
39char *head0 = "Rank Owner Job Files";
40char *head1 = "Total Size\n";
41d14893
RC
41
42/*
43 * Display the current state of the queue. Format = 1 if long format.
44 */
45displayq(format)
46 int format;
47{
48 register struct queue *q;
49 register int i, nitems, fd;
50 struct queue **queue;
51 struct stat statb;
52 FILE *fp;
53
41d14893
RC
54 lflag = format;
55 totsize = 0;
56 rank = -1;
57
58 if ((i = pgetent(line, printer)) < 0)
59 fatal("cannot open printer description file");
60 else if (i == 0)
61 fatal("unknown printer");
62 if ((LP = pgetstr("lp", &bp)) == NULL)
63 LP = DEFDEVLP;
64 if ((RP = pgetstr("rp", &bp)) == NULL)
755aa7aa 65 RP = DEFLP;
41d14893
RC
66 if ((SD = pgetstr("sd", &bp)) == NULL)
67 SD = DEFSPOOL;
68 if ((LO = pgetstr("lo", &bp)) == NULL)
69 LO = DEFLOCK;
70 if ((ST = pgetstr("st", &bp)) == NULL)
71 ST = DEFSTAT;
72 RM = pgetstr("rm", &bp);
73
74 /*
75 * If there is no local printer, then print the queue on
76 * the remote machine and then what's in the queue here.
77 * Note that a file in transit may not show up in either queue.
78 */
79 if (*LP == '\0') {
80 register char *cp;
81 char c;
82
83 sendtorem++;
84 (void) sprintf(line, "%c%s", format + '\3', RP);
85 cp = line;
86 for (i = 0; i < requests; i++) {
87 cp += strlen(cp);
88 (void) sprintf(cp, " %d", requ[i]);
89 }
90 for (i = 0; i < users; i++) {
91 cp += strlen(cp);
92 *cp++ = ' ';
93 strcpy(cp, user[i]);
94 }
95 strcat(line, "\n");
e923dc6a 96 fd = getport(RM);
41d14893
RC
97 if (fd < 0) {
98 if (from != host)
99 printf("%s: ", host);
100 printf("connection to %s is down\n", RM);
101 } else {
102 i = strlen(line);
103 if (write(fd, line, i) != i)
104 fatal("Lost connection");
105 while ((i = read(fd, line, sizeof(line))) > 0)
106 (void) fwrite(line, 1, i, stdout);
107 (void) close(fd);
108 }
109 }
110 /*
111 * Find all the control files in the spooling directory
112 */
113 if (chdir(SD) < 0)
114 fatal("cannot chdir to spooling directory");
115 if ((nitems = getq(&queue)) < 0)
116 fatal("cannot examine spooling area\n");
1fc2c7db
RC
117 if (stat(LO, &statb) >= 0) {
118 if ((statb.st_mode & 0110) && sendtorem)
119 printf("\n");
120 if (statb.st_mode & 0100) {
121 if (sendtorem)
122 printf("%s: ", host);
123 printf("Warning: %s is down: ", printer);
124 fd = open(ST, O_RDONLY);
125 if (fd >= 0) {
126 (void) flock(fd, LOCK_SH);
127 while ((i = read(fd, line, sizeof(line))) > 0)
128 (void) fwrite(line, 1, i, stdout);
129 (void) close(fd); /* unlocks as well */
130 } else
131 putchar('\n');
132 }
133 if (statb.st_mode & 010) {
134 if (sendtorem)
135 printf("%s: ", host);
136 printf("Warning: %s queue is turned off\n", printer);
137 }
9729d3b0
RC
138 }
139 if (nitems == 0) {
140 if (!sendtorem)
141 printf("no entries\n");
41d14893
RC
142 return(0);
143 }
144 fp = fopen(LO, "r");
8fed920b
RC
145 if (fp == NULL)
146 warn();
147 else {
148 register char *cp;
149
150 /* get daemon pid */
151 cp = current;
41d14893
RC
152 while ((*cp = getc(fp)) != EOF && *cp != '\n')
153 cp++;
154 *cp = '\0';
8fed920b 155 i = atoi(current);
815c5da6 156 if (i <= 0 || kill(i, 0) < 0)
8fed920b
RC
157 warn();
158 else {
159 /* read current file name */
160 cp = current;
161 while ((*cp = getc(fp)) != EOF && *cp != '\n')
162 cp++;
163 *cp = '\0';
164 /*
165 * Print the status file.
166 */
167 if (sendtorem)
168 printf("\n%s: ", host);
169 fd = open(ST, O_RDONLY);
170 if (fd >= 0) {
171 (void) flock(fd, LOCK_SH);
172 while ((i = read(fd, line, sizeof(line))) > 0)
173 (void) fwrite(line, 1, i, stdout);
174 (void) close(fd); /* unlocks as well */
175 } else
176 putchar('\n');
177 }
178 (void) fclose(fp);
41d14893
RC
179 }
180 /*
181 * Now, examine the control files and print out the jobs to
182 * be done for each user.
183 */
41d14893
RC
184 if (!lflag)
185 header();
186 for (i = 0; i < nitems; i++) {
187 q = queue[i];
188 inform(q->q_name);
189 free(q);
190 }
191 free(queue);
192 return(nitems-garbage);
193}
194
8fed920b
RC
195/*
196 * Print a warning message if there is no daemon present.
197 */
198warn()
199{
8fed920b
RC
200 if (sendtorem)
201 printf("\n%s: ", host);
1fc2c7db 202 printf("Warning: no daemon present\n");
8fed920b
RC
203 current[0] = '\0';
204}
205
41d14893
RC
206/*
207 * Print the header for the short listing format
208 */
209header()
210{
211 printf(head0);
212 col = strlen(head0)+1;
213 blankfill(SIZCOL);
214 printf(head1);
215}
216
217inform(cf)
218 char *cf;
219{
220 register int j, k;
221 register char *cp;
222 FILE *cfp;
223
224 /*
225 * There's a chance the control file has gone away
226 * in the meantime; if this is the case just keep going
227 */
228 if ((cfp = fopen(cf, "r")) == NULL)
229 return;
230
231 if (rank < 0)
232 rank = 0;
233 if (sendtorem || garbage || strcmp(cf, current))
234 rank++;
235 j = 0;
236 while (getline(cfp)) {
237 switch (line[0]) {
238 case 'P': /* Was this file specified in the user's list? */
239 if (!inlist(line+1, cf)) {
240 fclose(cfp);
241 return;
242 }
243 if (lflag) {
244 printf("\n%s: ", line+1);
245 col = strlen(line+1) + 2;
246 prank(rank);
247 blankfill(JOBCOL);
248 printf(" [job %s]\n", cf+3);
249 } else {
250 col = 0;
251 prank(rank);
252 blankfill(OWNCOL);
253 printf("%-10s %-3d ", line+1, atoi(cf+3));
254 col += 16;
255 first = 1;
256 }
257 continue;
258 default: /* some format specifer and file name? */
259 if (line[0] < 'a' || line[0] > 'z')
260 continue;
261 if (j == 0 || strcmp(file, line+1) != 0)
262 strcpy(file, line+1);
263 j++;
264 continue;
265 case 'N':
266 show(line+1, file, j);
267 file[0] = '\0';
268 j = 0;
269 }
270 }
271 fclose(cfp);
272 if (!lflag) {
273 blankfill(SIZCOL);
274 printf("%D bytes\n", totsize);
275 totsize = 0;
276 }
277}
278
279inlist(name, file)
280 char *name, *file;
281{
282 register int *r, n;
283 register char **u, *cp;
284
285 if (users == 0 && requests == 0)
286 return(1);
287 /*
288 * Check to see if it's in the user list
289 */
290 for (u = user; u < &user[users]; u++)
291 if (!strcmp(*u, name))
292 return(1);
293 /*
294 * Check the request list
295 */
296 for (n = 0, cp = file+3; isdigit(*cp); )
297 n = n * 10 + (*cp++ - '0');
298 for (r = requ; r < &requ[requests]; r++)
299 if (*r == n && !strcmp(cp, from))
300 return(1);
301 return(0);
302}
303
304show(nfile, file, copies)
305 register char *nfile, *file;
306{
307 if (strcmp(nfile, " ") == 0)
308 nfile = "(standard input)";
309 if (lflag)
310 ldump(nfile, file, copies);
311 else
312 dump(nfile, file, copies);
313}
314
315/*
316 * Fill the line with blanks to the specified column
317 */
318blankfill(n)
319 register int n;
320{
321 while (col++ < n)
322 putchar(' ');
323}
324
325/*
326 * Give the abbreviated dump of the file names
327 */
328dump(nfile, file, copies)
329 char *nfile, *file;
330{
331 register short n, fill;
332 struct stat lbuf;
333
334 /*
335 * Print as many files as will fit
336 * (leaving room for the total size)
337 */
338 fill = first ? 0 : 2; /* fill space for ``, '' */
339 if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
340 if (col < SIZCOL) {
341 printf(" ..."), col += 4;
342 blankfill(SIZCOL);
343 }
344 } else {
345 if (first)
346 first = 0;
347 else
348 printf(", ");
349 printf("%s", nfile);
350 col += n+fill;
351 }
352 if (*file && !stat(file, &lbuf))
353 totsize += copies * lbuf.st_size;
354}
355
356/*
357 * Print the long info about the file
358 */
359ldump(nfile, file, copies)
360 char *nfile, *file;
361{
362 struct stat lbuf;
363
364 putchar('\t');
365 if (copies > 1)
366 printf("%-2d copies of %-19s", copies, nfile);
367 else
368 printf("%-32s", nfile);
369 if (*file && !stat(file, &lbuf))
370 printf(" %D bytes", lbuf.st_size);
371 else
372 printf(" ??? bytes");
373 putchar('\n');
374}
375
376/*
377 * Print the job's rank in the queue,
378 * update col for screen management
379 */
380prank(n)
381{
382 char line[100];
383 static char *r[] = {
384 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
385 };
386
387 if (n == 0) {
388 printf("active");
389 col += 6;
390 return;
391 }
392 if ((n/10) == 1)
393 (void) sprintf(line, "%dth", n);
394 else
395 (void) sprintf(line, "%d%s", n, r[n%10]);
396 col += strlen(line);
397 printf("%s", line);
398}