displayq.c revision 15648
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1983, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 3515648Sjoergstatic char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95"; 361553Srgrimes#endif /* not lint */ 371553Srgrimes 381553Srgrimes#include <sys/param.h> 391553Srgrimes#include <sys/stat.h> 4015648Sjoerg#include <sys/file.h> 411553Srgrimes 421553Srgrimes#include <signal.h> 431553Srgrimes#include <fcntl.h> 441553Srgrimes#include <dirent.h> 451553Srgrimes#include <unistd.h> 461553Srgrimes#include <stdio.h> 471553Srgrimes#include <stdlib.h> 481553Srgrimes#include <string.h> 491553Srgrimes#include <ctype.h> 501553Srgrimes#include "lp.h" 511553Srgrimes#include "lp.local.h" 521553Srgrimes#include "pathnames.h" 531553Srgrimes 541553Srgrimes/* 551553Srgrimes * Routines to display the state of the queue. 561553Srgrimes */ 571553Srgrimes#define JOBCOL 40 /* column for job # in -l format */ 581553Srgrimes#define OWNCOL 7 /* start of Owner column in normal */ 591553Srgrimes#define SIZCOL 62 /* start of Size column in normal */ 601553Srgrimes 611553Srgrimes/* 621553Srgrimes * Stuff for handling job specifications 631553Srgrimes */ 641553Srgrimesextern int requ[]; /* job number of spool entries */ 651553Srgrimesextern int requests; /* # of spool requests */ 661553Srgrimesextern char *user[]; /* users to process */ 671553Srgrimesextern int users; /* # of users in user array */ 681553Srgrimes 691553Srgrimesstatic int col; /* column on screen */ 701553Srgrimesstatic char current[40]; /* current file being printed */ 711553Srgrimesstatic char file[132]; /* print file name */ 721553Srgrimesstatic int first; /* first file in ``files'' column? */ 731553Srgrimesstatic int garbage; /* # of garbage cf files */ 741553Srgrimesstatic int lflag; /* long output option */ 751553Srgrimesstatic int rank; /* order to be printed (-1=none, 0=active) */ 761553Srgrimesstatic long totsize; /* total print job size in bytes */ 771553Srgrimes 781553Srgrimesstatic char *head0 = "Rank Owner Job Files"; 791553Srgrimesstatic char *head1 = "Total Size\n"; 801553Srgrimes 811553Srgrimes/* 821553Srgrimes * Display the current state of the queue. Format = 1 if long format. 831553Srgrimes */ 841553Srgrimesvoid 851553Srgrimesdisplayq(format) 861553Srgrimes int format; 871553Srgrimes{ 881553Srgrimes register struct queue *q; 891553Srgrimes register int i, nitems, fd; 901553Srgrimes register char *cp; 911553Srgrimes struct queue **queue; 921553Srgrimes struct stat statb; 931553Srgrimes FILE *fp; 941553Srgrimes 951553Srgrimes lflag = format; 961553Srgrimes totsize = 0; 971553Srgrimes rank = -1; 981553Srgrimes if ((i = cgetent(&bp, printcapdb, printer)) == -2) 991553Srgrimes fatal("can't open printer description file"); 1001553Srgrimes else if (i == -1) 1011553Srgrimes fatal("unknown printer"); 1021553Srgrimes else if (i == -3) 1031553Srgrimes fatal("potential reference loop detected in printcap file"); 1041553Srgrimes if (cgetstr(bp, "lp", &LP) < 0) 1051553Srgrimes LP = _PATH_DEFDEVLP; 1061553Srgrimes if (cgetstr(bp, "rp", &RP) < 0) 1071553Srgrimes RP = DEFLP; 1081553Srgrimes if (cgetstr(bp, "sd", &SD) < 0) 1091553Srgrimes SD = _PATH_DEFSPOOL; 1101553Srgrimes if (cgetstr(bp,"lo", &LO) < 0) 1111553Srgrimes LO = DEFLOCK; 1121553Srgrimes if (cgetstr(bp, "st", &ST) < 0) 1131553Srgrimes ST = DEFSTAT; 1141553Srgrimes cgetstr(bp, "rm", &RM); 1151553Srgrimes if (cp = checkremote()) 1161553Srgrimes printf("Warning: %s\n", cp); 1171553Srgrimes 1181553Srgrimes /* 1191553Srgrimes * Print out local queue 1201553Srgrimes * Find all the control files in the spooling directory 1211553Srgrimes */ 1221553Srgrimes if (chdir(SD) < 0) 1231553Srgrimes fatal("cannot chdir to spooling directory"); 1241553Srgrimes if ((nitems = getq(&queue)) < 0) 1251553Srgrimes fatal("cannot examine spooling area\n"); 1261553Srgrimes if (stat(LO, &statb) >= 0) { 1271553Srgrimes if (statb.st_mode & 0100) { 12815648Sjoerg if (remote) 1291553Srgrimes printf("%s: ", host); 1301553Srgrimes printf("Warning: %s is down: ", printer); 1311553Srgrimes fd = open(ST, O_RDONLY); 1321553Srgrimes if (fd >= 0) { 1331553Srgrimes (void) flock(fd, LOCK_SH); 1341553Srgrimes while ((i = read(fd, line, sizeof(line))) > 0) 1351553Srgrimes (void) fwrite(line, 1, i, stdout); 1361553Srgrimes (void) close(fd); /* unlocks as well */ 1371553Srgrimes } else 1381553Srgrimes putchar('\n'); 1391553Srgrimes } 1401553Srgrimes if (statb.st_mode & 010) { 14115648Sjoerg if (remote) 1421553Srgrimes printf("%s: ", host); 1431553Srgrimes printf("Warning: %s queue is turned off\n", printer); 1441553Srgrimes } 1451553Srgrimes } 1461553Srgrimes 1471553Srgrimes if (nitems) { 1481553Srgrimes fp = fopen(LO, "r"); 1491553Srgrimes if (fp == NULL) 1501553Srgrimes warn(); 1511553Srgrimes else { 1521553Srgrimes /* get daemon pid */ 1531553Srgrimes cp = current; 15415648Sjoerg while ((i = getc(fp)) != EOF && i != '\n') 15515648Sjoerg *cp++ = i; 1561553Srgrimes *cp = '\0'; 1571553Srgrimes i = atoi(current); 1581553Srgrimes if (i <= 0 || kill(i, 0) < 0) 1591553Srgrimes warn(); 1601553Srgrimes else { 1611553Srgrimes /* read current file name */ 1621553Srgrimes cp = current; 16315648Sjoerg while ((i = getc(fp)) != EOF && i != '\n') 16415648Sjoerg *cp++ = i; 1651553Srgrimes *cp = '\0'; 1661553Srgrimes /* 1671553Srgrimes * Print the status file. 1681553Srgrimes */ 16915648Sjoerg if (remote) 1701553Srgrimes printf("%s: ", host); 1711553Srgrimes fd = open(ST, O_RDONLY); 1721553Srgrimes if (fd >= 0) { 1731553Srgrimes (void) flock(fd, LOCK_SH); 1741553Srgrimes while ((i = read(fd, line, sizeof(line))) > 0) 1751553Srgrimes (void) fwrite(line, 1, i, stdout); 1761553Srgrimes (void) close(fd); /* unlocks as well */ 1771553Srgrimes } else 1781553Srgrimes putchar('\n'); 1791553Srgrimes } 1801553Srgrimes (void) fclose(fp); 1811553Srgrimes } 1821553Srgrimes /* 1831553Srgrimes * Now, examine the control files and print out the jobs to 1841553Srgrimes * be done for each user. 1851553Srgrimes */ 1861553Srgrimes if (!lflag) 1871553Srgrimes header(); 1881553Srgrimes for (i = 0; i < nitems; i++) { 1891553Srgrimes q = queue[i]; 1901553Srgrimes inform(q->q_name); 1911553Srgrimes free(q); 1921553Srgrimes } 1931553Srgrimes free(queue); 1941553Srgrimes } 19515648Sjoerg if (!remote) { 1961553Srgrimes if (nitems == 0) 1971553Srgrimes puts("no entries"); 1981553Srgrimes return; 1991553Srgrimes } 2001553Srgrimes 2011553Srgrimes /* 2021553Srgrimes * Print foreign queue 2031553Srgrimes * Note that a file in transit may show up in either queue. 2041553Srgrimes */ 2051553Srgrimes if (nitems) 2061553Srgrimes putchar('\n'); 2071553Srgrimes (void) sprintf(line, "%c%s", format + '\3', RP); 2081553Srgrimes cp = line; 2091553Srgrimes for (i = 0; i < requests; i++) { 2101553Srgrimes cp += strlen(cp); 2111553Srgrimes (void) sprintf(cp, " %d", requ[i]); 2121553Srgrimes } 2131553Srgrimes for (i = 0; i < users; i++) { 2141553Srgrimes cp += strlen(cp); 2151553Srgrimes *cp++ = ' '; 2161553Srgrimes (void) strcpy(cp, user[i]); 2171553Srgrimes } 2181553Srgrimes strcat(line, "\n"); 21915648Sjoerg fd = getport(RM, 0); 2201553Srgrimes if (fd < 0) { 2211553Srgrimes if (from != host) 2221553Srgrimes printf("%s: ", host); 2231553Srgrimes printf("connection to %s is down\n", RM); 2241553Srgrimes } 2251553Srgrimes else { 2261553Srgrimes i = strlen(line); 2271553Srgrimes if (write(fd, line, i) != i) 2281553Srgrimes fatal("Lost connection"); 2291553Srgrimes while ((i = read(fd, line, sizeof(line))) > 0) 2301553Srgrimes (void) fwrite(line, 1, i, stdout); 2311553Srgrimes (void) close(fd); 2321553Srgrimes } 2331553Srgrimes} 2341553Srgrimes 2351553Srgrimes/* 2361553Srgrimes * Print a warning message if there is no daemon present. 2371553Srgrimes */ 2381553Srgrimesvoid 2391553Srgrimeswarn() 2401553Srgrimes{ 24115648Sjoerg if (remote) 2421553Srgrimes printf("\n%s: ", host); 2431553Srgrimes puts("Warning: no daemon present"); 2441553Srgrimes current[0] = '\0'; 2451553Srgrimes} 2461553Srgrimes 2471553Srgrimes/* 2481553Srgrimes * Print the header for the short listing format 2491553Srgrimes */ 2501553Srgrimesvoid 2511553Srgrimesheader() 2521553Srgrimes{ 2531553Srgrimes printf(head0); 2541553Srgrimes col = strlen(head0)+1; 2551553Srgrimes blankfill(SIZCOL); 2561553Srgrimes printf(head1); 2571553Srgrimes} 2581553Srgrimes 2591553Srgrimesvoid 2601553Srgrimesinform(cf) 2611553Srgrimes char *cf; 2621553Srgrimes{ 2631553Srgrimes register int j; 2641553Srgrimes FILE *cfp; 2651553Srgrimes 2661553Srgrimes /* 2671553Srgrimes * There's a chance the control file has gone away 2681553Srgrimes * in the meantime; if this is the case just keep going 2691553Srgrimes */ 2701553Srgrimes if ((cfp = fopen(cf, "r")) == NULL) 2711553Srgrimes return; 2721553Srgrimes 2731553Srgrimes if (rank < 0) 2741553Srgrimes rank = 0; 27515648Sjoerg if (remote || garbage || strcmp(cf, current)) 2761553Srgrimes rank++; 2771553Srgrimes j = 0; 2781553Srgrimes while (getline(cfp)) { 2791553Srgrimes switch (line[0]) { 2801553Srgrimes case 'P': /* Was this file specified in the user's list? */ 2811553Srgrimes if (!inlist(line+1, cf)) { 2821553Srgrimes fclose(cfp); 2831553Srgrimes return; 2841553Srgrimes } 2851553Srgrimes if (lflag) { 2861553Srgrimes printf("\n%s: ", line+1); 2871553Srgrimes col = strlen(line+1) + 2; 2881553Srgrimes prank(rank); 2891553Srgrimes blankfill(JOBCOL); 2901553Srgrimes printf(" [job %s]\n", cf+3); 2911553Srgrimes } else { 2921553Srgrimes col = 0; 2931553Srgrimes prank(rank); 2941553Srgrimes blankfill(OWNCOL); 2951553Srgrimes printf("%-10s %-3d ", line+1, atoi(cf+3)); 2961553Srgrimes col += 16; 2971553Srgrimes first = 1; 2981553Srgrimes } 2991553Srgrimes continue; 3001553Srgrimes default: /* some format specifer and file name? */ 3011553Srgrimes if (line[0] < 'a' || line[0] > 'z') 3021553Srgrimes continue; 3031553Srgrimes if (j == 0 || strcmp(file, line+1) != 0) 3041553Srgrimes (void) strcpy(file, line+1); 3051553Srgrimes j++; 3061553Srgrimes continue; 3071553Srgrimes case 'N': 3081553Srgrimes show(line+1, file, j); 3091553Srgrimes file[0] = '\0'; 3101553Srgrimes j = 0; 3111553Srgrimes } 3121553Srgrimes } 3131553Srgrimes fclose(cfp); 3141553Srgrimes if (!lflag) { 3151553Srgrimes blankfill(SIZCOL); 3161553Srgrimes printf("%ld bytes\n", totsize); 3171553Srgrimes totsize = 0; 3181553Srgrimes } 3191553Srgrimes} 3201553Srgrimes 3211553Srgrimesint 3221553Srgrimesinlist(name, file) 3231553Srgrimes char *name, *file; 3241553Srgrimes{ 3251553Srgrimes register int *r, n; 3261553Srgrimes register char **u, *cp; 3271553Srgrimes 3281553Srgrimes if (users == 0 && requests == 0) 3291553Srgrimes return(1); 3301553Srgrimes /* 3311553Srgrimes * Check to see if it's in the user list 3321553Srgrimes */ 3331553Srgrimes for (u = user; u < &user[users]; u++) 3341553Srgrimes if (!strcmp(*u, name)) 3351553Srgrimes return(1); 3361553Srgrimes /* 3371553Srgrimes * Check the request list 3381553Srgrimes */ 3391553Srgrimes for (n = 0, cp = file+3; isdigit(*cp); ) 3401553Srgrimes n = n * 10 + (*cp++ - '0'); 3411553Srgrimes for (r = requ; r < &requ[requests]; r++) 3421553Srgrimes if (*r == n && !strcmp(cp, from)) 3431553Srgrimes return(1); 3441553Srgrimes return(0); 3451553Srgrimes} 3461553Srgrimes 3471553Srgrimesvoid 3481553Srgrimesshow(nfile, file, copies) 3491553Srgrimes register char *nfile, *file; 3501553Srgrimes int copies; 3511553Srgrimes{ 3521553Srgrimes if (strcmp(nfile, " ") == 0) 3531553Srgrimes nfile = "(standard input)"; 3541553Srgrimes if (lflag) 3551553Srgrimes ldump(nfile, file, copies); 3561553Srgrimes else 3571553Srgrimes dump(nfile, file, copies); 3581553Srgrimes} 3591553Srgrimes 3601553Srgrimes/* 3611553Srgrimes * Fill the line with blanks to the specified column 3621553Srgrimes */ 3631553Srgrimesvoid 3641553Srgrimesblankfill(n) 3651553Srgrimes register int n; 3661553Srgrimes{ 3671553Srgrimes while (col++ < n) 3681553Srgrimes putchar(' '); 3691553Srgrimes} 3701553Srgrimes 3711553Srgrimes/* 3721553Srgrimes * Give the abbreviated dump of the file names 3731553Srgrimes */ 3741553Srgrimesvoid 3751553Srgrimesdump(nfile, file, copies) 3761553Srgrimes char *nfile, *file; 3771553Srgrimes int copies; 3781553Srgrimes{ 3791553Srgrimes register short n, fill; 3801553Srgrimes struct stat lbuf; 3811553Srgrimes 3821553Srgrimes /* 3831553Srgrimes * Print as many files as will fit 3841553Srgrimes * (leaving room for the total size) 3851553Srgrimes */ 3861553Srgrimes fill = first ? 0 : 2; /* fill space for ``, '' */ 3871553Srgrimes if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 3881553Srgrimes if (col < SIZCOL) { 3891553Srgrimes printf(" ..."), col += 4; 3901553Srgrimes blankfill(SIZCOL); 3911553Srgrimes } 3921553Srgrimes } else { 3931553Srgrimes if (first) 3941553Srgrimes first = 0; 3951553Srgrimes else 3961553Srgrimes printf(", "); 3971553Srgrimes printf("%s", nfile); 3981553Srgrimes col += n+fill; 3991553Srgrimes } 4001553Srgrimes if (*file && !stat(file, &lbuf)) 4011553Srgrimes totsize += copies * lbuf.st_size; 4021553Srgrimes} 4031553Srgrimes 4041553Srgrimes/* 4051553Srgrimes * Print the long info about the file 4061553Srgrimes */ 4071553Srgrimesvoid 4081553Srgrimesldump(nfile, file, copies) 4091553Srgrimes char *nfile, *file; 4101553Srgrimes int copies; 4111553Srgrimes{ 4121553Srgrimes struct stat lbuf; 4131553Srgrimes 4141553Srgrimes putchar('\t'); 4151553Srgrimes if (copies > 1) 4161553Srgrimes printf("%-2d copies of %-19s", copies, nfile); 4171553Srgrimes else 4181553Srgrimes printf("%-32s", nfile); 4191553Srgrimes if (*file && !stat(file, &lbuf)) 42015646Sjoerg printf(" %qd bytes", lbuf.st_size); 4211553Srgrimes else 4221553Srgrimes printf(" ??? bytes"); 4231553Srgrimes putchar('\n'); 4241553Srgrimes} 4251553Srgrimes 4261553Srgrimes/* 4271553Srgrimes * Print the job's rank in the queue, 4281553Srgrimes * update col for screen management 4291553Srgrimes */ 4301553Srgrimesvoid 4311553Srgrimesprank(n) 4321553Srgrimes int n; 4331553Srgrimes{ 4341553Srgrimes char rline[100]; 4351553Srgrimes static char *r[] = { 4361553Srgrimes "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 4371553Srgrimes }; 4381553Srgrimes 4391553Srgrimes if (n == 0) { 4401553Srgrimes printf("active"); 4411553Srgrimes col += 6; 4421553Srgrimes return; 4431553Srgrimes } 4441553Srgrimes if ((n/10)%10 == 1) 4451553Srgrimes (void)snprintf(rline, sizeof(rline), "%dth", n); 4461553Srgrimes else 4471553Srgrimes (void)snprintf(rline, sizeof(rline), "%d%s", n, r[n%10]); 4481553Srgrimes col += strlen(rline); 4491553Srgrimes printf("%s", rline); 4501553Srgrimes} 451