1 /* $NetBSD: displayq.c,v 1.33 2009/01/18 09:57:26 lukem Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95";
37 __RCSID("$NetBSD: displayq.c,v 1.33 2009/01/18 09:57:26 lukem Exp $");
41 #include <sys/param.h>
55 #include "pathnames.h"
58 * Routines to display the state of the queue.
60 #define JOBCOL 40 /* column for job # in -l format */
61 #define OWNCOL 7 /* start of Owner column in normal */
62 #define SIZCOL 62 /* start of Size column in normal */
65 * Stuff for handling job specifications
67 extern int requ
[]; /* job number of spool entries */
68 extern int requests
; /* # of spool requests */
69 extern char *user
[]; /* users to process */
70 extern int users
; /* # of users in user array */
72 extern uid_t uid
, euid
;
74 static int col
; /* column on screen */
75 static char current
[MAXPATHLEN
]; /* current file being printed */
76 static char fname
[MAXPATHLEN
]; /* print file name */
77 static int first
; /* first file in ``files'' column? */
78 static int garbage
; /* # of garbage cf files */
79 static int lflag
; /* long output option */
80 static int rank
; /* order to be printed (-1=none, 0=active) */
81 static long totsize
; /* total print job size in bytes */
83 static const char head0
[] = "Rank Owner Job Files";
84 static const char head1
[] = "Total Size\n";
86 static void alarmer(int);
88 int wait_time
= 300; /* time out after 5 minutes by default */
91 * Display the current state of the queue. Format = 1 if long format.
97 int i
, nitems
, fd
, ret
;
106 getprintcap(printer
);
109 * Print out local queue
110 * Find all the control files in the spooling directory
114 fatal("cannot chdir to spooling directory");
116 if ((nitems
= getq(&queue
)) < 0)
117 fatal("cannot examine spooling area\n");
119 ret
= stat(LO
, &statb
);
122 if (statb
.st_mode
& S_IXUSR
) {
124 printf("%s: ", host
);
125 printf("Warning: %s is down: ", printer
);
127 fd
= open(ST
, O_RDONLY
);
130 (void)flock(fd
, LOCK_SH
);
131 while ((i
= read(fd
, line
, sizeof(line
))) > 0)
132 (void)fwrite(line
, 1, (size_t)i
, stdout
);
133 (void)close(fd
); /* unlocks as well */
137 if (statb
.st_mode
& S_IXGRP
) {
139 printf("%s: ", host
);
140 printf("Warning: %s queue is turned off\n", printer
);
153 ecp
= cp
+ sizeof(current
) - 1;
154 while ((i
= getc(fp
)) != EOF
&& i
!= '\n') {
170 /* read current file name */
172 ecp
= cp
+ sizeof(current
) - 1;
173 while ((i
= getc(fp
)) != EOF
&& i
!= '\n') {
179 * Print the status file.
182 printf("%s: ", host
);
184 fd
= open(ST
, O_RDONLY
);
187 (void)flock(fd
, LOCK_SH
);
188 while ((i
= read(fd
, line
, sizeof(line
))) > 0)
189 (void)fwrite(line
, 1, (size_t)i
, stdout
);
190 (void)close(fd
); /* unlocks as well */
197 * Now, examine the control files and print out the jobs to
198 * be done for each user.
202 for (i
= 0; i
< nitems
; i
++) {
207 freeq(queue
, nitems
);
215 * Print foreign queue
216 * Note that a file in transit may show up in either queue.
220 (void)snprintf(line
, sizeof(line
), "%c%s", format
+ '\3', RP
);
222 ecp
= line
+ sizeof(line
);
224 i
< requests
&& (size_t)(cp
- line
+ 11) < sizeof(line
) - 2;
227 (void)snprintf(cp
, ecp
- cp
, " %d", requ
[i
]);
230 i
< users
&& cp
- line
+ 1 + strlen(user
[i
]) < sizeof(line
) - 2;
233 if ((size_t)(cp
- line
) > sizeof(line
) - 2)
236 /* truncation may happen */
237 (void)strlcpy(cp
, user
[i
], ecp
- cp
);
239 (void)strlcat(line
, "\n", sizeof(line
));
243 printf("%s: ", host
);
244 (void)printf("connection to %s is down\n", RM
);
247 struct sigaction osa
, nsa
;
250 if (write(fd
, line
, (size_t)i
) != i
)
251 fatal("Lost connection");
252 nsa
.sa_handler
= alarmer
;
253 sigemptyset(&nsa
.sa_mask
);
254 sigaddset(&nsa
.sa_mask
, SIGALRM
);
256 (void)sigaction(SIGALRM
, &nsa
, &osa
);
258 while ((i
= read(fd
, line
, sizeof(line
))) > 0) {
259 (void)fwrite(line
, 1, (size_t)i
, stdout
);
263 (void)sigaction(SIGALRM
, &osa
, NULL
);
275 * Print a warning message if there is no daemon present.
281 printf("\n%s: ", host
);
282 puts("Warning: no daemon present");
287 * Print the header for the short listing format
293 col
= strlen(head0
)+1;
299 inform(const char *cf
)
305 * There's a chance the control file has gone away
306 * in the meantime; if this is the case just keep going
309 if ((cfp
= fopen(cf
, "r")) == NULL
)
315 if (remote
|| garbage
|| strcmp(cf
, current
))
318 while (get_line(cfp
)) {
320 case 'P': /* Was this file specified in the user's list? */
321 if (!inlist(line
+1, cf
)) {
326 printf("\n%s: ", line
+1);
327 col
= strlen(line
+1) + 2;
330 printf(" [job %s]\n", cf
+3);
335 printf("%-10s %-3d ", line
+1, atoi(cf
+3));
340 default: /* some format specifer and file name? */
341 if (line
[0] < 'a' || line
[0] > 'z')
343 if (j
== 0 || strcmp(fname
, line
+1) != 0) {
344 (void)strlcpy(fname
, line
+1, sizeof(fname
));
349 show(line
+ 1, fname
, j
);
357 printf("%ld bytes\n", totsize
);
363 inlist(const char *name
, const char *file
)
369 if (users
== 0 && requests
== 0)
372 * Check to see if it's in the user list
374 for (u
= user
; u
< &user
[users
]; u
++)
375 if (!strcmp(*u
, name
))
378 * Check the request list
380 for (n
= 0, cp
= file
+3; isdigit((unsigned char)*cp
); )
381 n
= n
* 10 + (*cp
++ - '0');
382 for (r
= requ
; r
< &requ
[requests
]; r
++)
383 if (*r
== n
&& !strcmp(cp
, from
))
389 show(const char *nfile
, const char *file
, int copies
)
391 if (strcmp(nfile
, " ") == 0)
392 nfile
= "(standard input)";
394 ldump(nfile
, file
, copies
);
396 dump(nfile
, file
, copies
);
400 * Fill the line with blanks to the specified column
410 * Give the abbreviated dump of the file names
413 dump(const char *nfile
, const char *file
, int copies
)
419 * Print as many files as will fit
420 * (leaving room for the total size)
422 fill
= first
? 0 : 2; /* fill space for ``, '' */
423 if (((n
= strlen(nfile
)) + col
+ fill
) >= SIZCOL
-4) {
425 printf(" ..."), col
+= 4;
437 if (*file
&& !stat(file
, &lbuf
))
438 totsize
+= copies
* (long)lbuf
.st_size
;
443 * Print the long info about the file
446 ldump(const char *nfile
, const char *file
, int copies
)
452 printf("%-2d copies of %-19s", copies
, nfile
);
454 printf("%-32s", nfile
);
455 if (*file
&& !stat(file
, &lbuf
))
456 printf(" %lld bytes", (long long)lbuf
.st_size
);
458 printf(" ??? bytes");
463 * Print the job's rank in the queue,
464 * update col for screen management
470 static const char *r
[] = {
471 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
480 (void)snprintf(rline
, sizeof(rline
), "%dth", n
);
482 (void)snprintf(rline
, sizeof(rline
), "%d%s", n
, r
[n
%10]);
483 col
+= strlen(rline
);