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