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