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