BSD 4_2 release
[unix-history] / usr / src / usr.lib / lpr / displayq.c
CommitLineData
5f84f8f0 1#ifndef lint
0f4556f1 2static char sccsid[] = "@(#)displayq.c 4.9 (Berkeley) 7/17/83";
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
54266d1f
RC
23static int lflag; /* long output option */
24static char current[40]; /* current file being printed */
25static int garbage; /* # of garbage cf files */
26static int rank; /* order to be printed (-1=none, 0=active) */
27static long totsize; /* total print job size in bytes */
28static int first; /* first file in ``files'' column? */
29static int col; /* column on screen */
30static int sendtorem; /* are we sending to a remote? */
31static char file[132]; /* print file name */
41d14893 32
54266d1f
RC
33static char *head0 = "Rank Owner Job Files";
34static char *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");
9729d3b0 111 if (stat(LO, &statb) >= 0 && (statb.st_mode & 010)) {
41d14893
RC
112 if (sendtorem)
113 printf("\n%s: ", host);
9729d3b0
RC
114 printf("Warning: %s queue is turned off\n", printer);
115 }
116 if (nitems == 0) {
117 if (!sendtorem)
118 printf("no entries\n");
41d14893
RC
119 return(0);
120 }
121 fp = fopen(LO, "r");
8fed920b
RC
122 if (fp == NULL)
123 warn();
124 else {
125 register char *cp;
126
127 /* get daemon pid */
128 cp = current;
41d14893
RC
129 while ((*cp = getc(fp)) != EOF && *cp != '\n')
130 cp++;
131 *cp = '\0';
8fed920b
RC
132 i = atoi(current);
133 if (kill(i, 0) < 0)
134 warn();
135 else {
136 /* read current file name */
137 cp = current;
138 while ((*cp = getc(fp)) != EOF && *cp != '\n')
139 cp++;
140 *cp = '\0';
141 /*
142 * Print the status file.
143 */
144 if (sendtorem)
145 printf("\n%s: ", host);
146 fd = open(ST, O_RDONLY);
147 if (fd >= 0) {
148 (void) flock(fd, LOCK_SH);
149 while ((i = read(fd, line, sizeof(line))) > 0)
150 (void) fwrite(line, 1, i, stdout);
151 (void) close(fd); /* unlocks as well */
152 } else
153 putchar('\n');
154 }
155 (void) fclose(fp);
41d14893
RC
156 }
157 /*
158 * Now, examine the control files and print out the jobs to
159 * be done for each user.
160 */
41d14893
RC
161 if (!lflag)
162 header();
163 for (i = 0; i < nitems; i++) {
164 q = queue[i];
165 inform(q->q_name);
166 free(q);
167 }
168 free(queue);
169 return(nitems-garbage);
170}
171
8fed920b
RC
172/*
173 * Print a warning message if there is no daemon present.
174 */
175warn()
176{
177 struct stat statb;
178
179 if (sendtorem)
180 printf("\n%s: ", host);
181 if (stat(LO, &statb) >= 0 && (statb.st_mode & 0100))
182 printf("Warning: %s is down\n", printer);
183 else
184 printf("Warning: no daemon present\n");
185 current[0] = '\0';
186}
187
41d14893
RC
188/*
189 * Print the header for the short listing format
190 */
54266d1f 191static
41d14893
RC
192header()
193{
194 printf(head0);
195 col = strlen(head0)+1;
196 blankfill(SIZCOL);
197 printf(head1);
198}
199
54266d1f 200static
41d14893
RC
201inform(cf)
202 char *cf;
203{
204 register int j, k;
205 register char *cp;
206 FILE *cfp;
207
208 /*
209 * There's a chance the control file has gone away
210 * in the meantime; if this is the case just keep going
211 */
212 if ((cfp = fopen(cf, "r")) == NULL)
213 return;
214
215 if (rank < 0)
216 rank = 0;
217 if (sendtorem || garbage || strcmp(cf, current))
218 rank++;
219 j = 0;
220 while (getline(cfp)) {
221 switch (line[0]) {
222 case 'P': /* Was this file specified in the user's list? */
223 if (!inlist(line+1, cf)) {
224 fclose(cfp);
225 return;
226 }
227 if (lflag) {
228 printf("\n%s: ", line+1);
229 col = strlen(line+1) + 2;
230 prank(rank);
231 blankfill(JOBCOL);
232 printf(" [job %s]\n", cf+3);
233 } else {
234 col = 0;
235 prank(rank);
236 blankfill(OWNCOL);
237 printf("%-10s %-3d ", line+1, atoi(cf+3));
238 col += 16;
239 first = 1;
240 }
241 continue;
242 default: /* some format specifer and file name? */
243 if (line[0] < 'a' || line[0] > 'z')
244 continue;
245 if (j == 0 || strcmp(file, line+1) != 0)
246 strcpy(file, line+1);
247 j++;
248 continue;
249 case 'N':
250 show(line+1, file, j);
251 file[0] = '\0';
252 j = 0;
253 }
254 }
255 fclose(cfp);
256 if (!lflag) {
257 blankfill(SIZCOL);
258 printf("%D bytes\n", totsize);
259 totsize = 0;
260 }
261}
262
54266d1f 263static
41d14893
RC
264inlist(name, file)
265 char *name, *file;
266{
267 register int *r, n;
268 register char **u, *cp;
269
270 if (users == 0 && requests == 0)
271 return(1);
272 /*
273 * Check to see if it's in the user list
274 */
275 for (u = user; u < &user[users]; u++)
276 if (!strcmp(*u, name))
277 return(1);
278 /*
279 * Check the request list
280 */
281 for (n = 0, cp = file+3; isdigit(*cp); )
282 n = n * 10 + (*cp++ - '0');
283 for (r = requ; r < &requ[requests]; r++)
284 if (*r == n && !strcmp(cp, from))
285 return(1);
286 return(0);
287}
288
54266d1f 289static
41d14893
RC
290show(nfile, file, copies)
291 register char *nfile, *file;
292{
293 if (strcmp(nfile, " ") == 0)
294 nfile = "(standard input)";
295 if (lflag)
296 ldump(nfile, file, copies);
297 else
298 dump(nfile, file, copies);
299}
300
301/*
302 * Fill the line with blanks to the specified column
303 */
54266d1f 304static
41d14893
RC
305blankfill(n)
306 register int n;
307{
308 while (col++ < n)
309 putchar(' ');
310}
311
312/*
313 * Give the abbreviated dump of the file names
314 */
54266d1f 315static
41d14893
RC
316dump(nfile, file, copies)
317 char *nfile, *file;
318{
319 register short n, fill;
320 struct stat lbuf;
321
322 /*
323 * Print as many files as will fit
324 * (leaving room for the total size)
325 */
326 fill = first ? 0 : 2; /* fill space for ``, '' */
327 if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
328 if (col < SIZCOL) {
329 printf(" ..."), col += 4;
330 blankfill(SIZCOL);
331 }
332 } else {
333 if (first)
334 first = 0;
335 else
336 printf(", ");
337 printf("%s", nfile);
338 col += n+fill;
339 }
340 if (*file && !stat(file, &lbuf))
341 totsize += copies * lbuf.st_size;
342}
343
344/*
345 * Print the long info about the file
346 */
54266d1f 347static
41d14893
RC
348ldump(nfile, file, copies)
349 char *nfile, *file;
350{
351 struct stat lbuf;
352
353 putchar('\t');
354 if (copies > 1)
355 printf("%-2d copies of %-19s", copies, nfile);
356 else
357 printf("%-32s", nfile);
358 if (*file && !stat(file, &lbuf))
359 printf(" %D bytes", lbuf.st_size);
360 else
361 printf(" ??? bytes");
362 putchar('\n');
363}
364
365/*
366 * Print the job's rank in the queue,
367 * update col for screen management
368 */
54266d1f 369static
41d14893
RC
370prank(n)
371{
372 char line[100];
373 static char *r[] = {
374 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
375 };
376
377 if (n == 0) {
378 printf("active");
379 col += 6;
380 return;
381 }
382 if ((n/10) == 1)
383 (void) sprintf(line, "%dth", n);
384 else
385 (void) sprintf(line, "%d%s", n, r[n%10]);
386 col += strlen(line);
387 printf("%s", line);
388}