getpass required
[unix-history] / usr / src / usr.sbin / lpr / common_source / displayq.c
CommitLineData
54266d1f 1/* displayq.c 4.5 83/06/02 */
41d14893
RC
2/*
3 * Routines to display the state of the queue.
4 */
5
6#include "lp.h"
7
54266d1f
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");
119 if (fp == NULL || flock(fileno(fp), FSHLOCK|FNBLOCK) == 0) {
120 if (fp != NULL)
121 fclose(fp);
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);
144 if ((fd = open(ST, FRDONLY|FSHLOCK)) >= 0) {
145 while ((i = read(fd, line, sizeof(line))) > 0)
146 (void) fwrite(line, 1, i, stdout);
147 (void) close(fd);
148 } else
149 putchar('\n');
41d14893
RC
150 }
151 /*
152 * Now, examine the control files and print out the jobs to
153 * be done for each user.
154 */
41d14893
RC
155 if (!lflag)
156 header();
157 for (i = 0; i < nitems; i++) {
158 q = queue[i];
159 inform(q->q_name);
160 free(q);
161 }
162 free(queue);
163 return(nitems-garbage);
164}
165
166/*
167 * Print the header for the short listing format
168 */
54266d1f 169static
41d14893
RC
170header()
171{
172 printf(head0);
173 col = strlen(head0)+1;
174 blankfill(SIZCOL);
175 printf(head1);
176}
177
54266d1f 178static
41d14893
RC
179inform(cf)
180 char *cf;
181{
182 register int j, k;
183 register char *cp;
184 FILE *cfp;
185
186 /*
187 * There's a chance the control file has gone away
188 * in the meantime; if this is the case just keep going
189 */
190 if ((cfp = fopen(cf, "r")) == NULL)
191 return;
192
193 if (rank < 0)
194 rank = 0;
195 if (sendtorem || garbage || strcmp(cf, current))
196 rank++;
197 j = 0;
198 while (getline(cfp)) {
199 switch (line[0]) {
200 case 'P': /* Was this file specified in the user's list? */
201 if (!inlist(line+1, cf)) {
202 fclose(cfp);
203 return;
204 }
205 if (lflag) {
206 printf("\n%s: ", line+1);
207 col = strlen(line+1) + 2;
208 prank(rank);
209 blankfill(JOBCOL);
210 printf(" [job %s]\n", cf+3);
211 } else {
212 col = 0;
213 prank(rank);
214 blankfill(OWNCOL);
215 printf("%-10s %-3d ", line+1, atoi(cf+3));
216 col += 16;
217 first = 1;
218 }
219 continue;
220 default: /* some format specifer and file name? */
221 if (line[0] < 'a' || line[0] > 'z')
222 continue;
223 if (j == 0 || strcmp(file, line+1) != 0)
224 strcpy(file, line+1);
225 j++;
226 continue;
227 case 'N':
228 show(line+1, file, j);
229 file[0] = '\0';
230 j = 0;
231 }
232 }
233 fclose(cfp);
234 if (!lflag) {
235 blankfill(SIZCOL);
236 printf("%D bytes\n", totsize);
237 totsize = 0;
238 }
239}
240
54266d1f 241static
41d14893
RC
242inlist(name, file)
243 char *name, *file;
244{
245 register int *r, n;
246 register char **u, *cp;
247
248 if (users == 0 && requests == 0)
249 return(1);
250 /*
251 * Check to see if it's in the user list
252 */
253 for (u = user; u < &user[users]; u++)
254 if (!strcmp(*u, name))
255 return(1);
256 /*
257 * Check the request list
258 */
259 for (n = 0, cp = file+3; isdigit(*cp); )
260 n = n * 10 + (*cp++ - '0');
261 for (r = requ; r < &requ[requests]; r++)
262 if (*r == n && !strcmp(cp, from))
263 return(1);
264 return(0);
265}
266
54266d1f 267static
41d14893
RC
268show(nfile, file, copies)
269 register char *nfile, *file;
270{
271 if (strcmp(nfile, " ") == 0)
272 nfile = "(standard input)";
273 if (lflag)
274 ldump(nfile, file, copies);
275 else
276 dump(nfile, file, copies);
277}
278
279/*
280 * Fill the line with blanks to the specified column
281 */
54266d1f 282static
41d14893
RC
283blankfill(n)
284 register int n;
285{
286 while (col++ < n)
287 putchar(' ');
288}
289
290/*
291 * Give the abbreviated dump of the file names
292 */
54266d1f 293static
41d14893
RC
294dump(nfile, file, copies)
295 char *nfile, *file;
296{
297 register short n, fill;
298 struct stat lbuf;
299
300 /*
301 * Print as many files as will fit
302 * (leaving room for the total size)
303 */
304 fill = first ? 0 : 2; /* fill space for ``, '' */
305 if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) {
306 if (col < SIZCOL) {
307 printf(" ..."), col += 4;
308 blankfill(SIZCOL);
309 }
310 } else {
311 if (first)
312 first = 0;
313 else
314 printf(", ");
315 printf("%s", nfile);
316 col += n+fill;
317 }
318 if (*file && !stat(file, &lbuf))
319 totsize += copies * lbuf.st_size;
320}
321
322/*
323 * Print the long info about the file
324 */
54266d1f 325static
41d14893
RC
326ldump(nfile, file, copies)
327 char *nfile, *file;
328{
329 struct stat lbuf;
330
331 putchar('\t');
332 if (copies > 1)
333 printf("%-2d copies of %-19s", copies, nfile);
334 else
335 printf("%-32s", nfile);
336 if (*file && !stat(file, &lbuf))
337 printf(" %D bytes", lbuf.st_size);
338 else
339 printf(" ??? bytes");
340 putchar('\n');
341}
342
343/*
344 * Print the job's rank in the queue,
345 * update col for screen management
346 */
54266d1f 347static
41d14893
RC
348prank(n)
349{
350 char line[100];
351 static char *r[] = {
352 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
353 };
354
355 if (n == 0) {
356 printf("active");
357 col += 6;
358 return;
359 }
360 if ((n/10) == 1)
361 (void) sprintf(line, "%dth", n);
362 else
363 (void) sprintf(line, "%d%s", n, r[n%10]);
364 col += strlen(line);
365 printf("%s", line);
366}