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