|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)displayq.c 4.9 (Berkeley) 7/17/83";
3: #endif
4:
5: /*
6: * Routines to display the state of the queue.
7: */
8:
9: #include "lp.h"
10:
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 */
14:
15: /*
16: * Stuff for handling job specifications
17: */
18: extern char *user[]; /* users to process */
19: extern int users; /* # of users in user array */
20: extern int requ[]; /* job number of spool entries */
21: extern int requests; /* # of spool requests */
22:
23: static int lflag; /* long output option */
24: static char current[40]; /* current file being printed */
25: static int garbage; /* # of garbage cf files */
26: static int rank; /* order to be printed (-1=none, 0=active) */
27: static long totsize; /* total print job size in bytes */
28: static int first; /* first file in ``files'' column? */
29: static int col; /* column on screen */
30: static int sendtorem; /* are we sending to a remote? */
31: static char file[132]; /* print file name */
32:
33: static char *head0 = "Rank Owner Job Files";
34: static char *head1 = "Total Size\n";
35:
36: /*
37: * Display the current state of the queue. Format = 1 if long format.
38: */
39: displayq(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:
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)
59: RP = DEFLP;
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");
90: fd = getport(RM);
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");
111: if (stat(LO, &statb) >= 0 && (statb.st_mode & 010)) {
112: if (sendtorem)
113: printf("\n%s: ", host);
114: printf("Warning: %s queue is turned off\n", printer);
115: }
116: if (nitems == 0) {
117: if (!sendtorem)
118: printf("no entries\n");
119: return(0);
120: }
121: fp = fopen(LO, "r");
122: if (fp == NULL)
123: warn();
124: else {
125: register char *cp;
126:
127: /* get daemon pid */
128: cp = current;
129: while ((*cp = getc(fp)) != EOF && *cp != '\n')
130: cp++;
131: *cp = '\0';
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);
156: }
157: /*
158: * Now, examine the control files and print out the jobs to
159: * be done for each user.
160: */
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:
172: /*
173: * Print a warning message if there is no daemon present.
174: */
175: warn()
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:
188: /*
189: * Print the header for the short listing format
190: */
191: static
192: header()
193: {
194: printf(head0);
195: col = strlen(head0)+1;
196: blankfill(SIZCOL);
197: printf(head1);
198: }
199:
200: static
201: inform(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:
263: static
264: inlist(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:
289: static
290: show(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: */
304: static
305: blankfill(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: */
315: static
316: dump(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: */
347: static
348: ldump(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: */
369: static
370: prank(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.