displayq.c revision 1553
159769Sgrog/* 259769Sgrog * Copyright (c) 1983, 1993 324424Swosch * The Regents of the University of California. All rights reserved. 424424Swosch * 524424Swosch * Redistribution and use in source and binary forms, with or without 624424Swosch * modification, are permitted provided that the following conditions 724424Swosch * are met: 824424Swosch * 1. Redistributions of source code must retain the above copyright 924424Swosch * notice, this list of conditions and the following disclaimer. 1024424Swosch * 2. Redistributions in binary form must reproduce the above copyright 1124424Swosch * notice, this list of conditions and the following disclaimer in the 1224424Swosch * documentation and/or other materials provided with the distribution. 1324424Swosch * 3. All advertising materials mentioning features or use of this software 1424424Swosch * must display the following acknowledgement: 1542704Swosch * This product includes software developed by the University of 1642704Swosch * California, Berkeley and its contributors. 1742704Swosch * 4. Neither the name of the University nor the names of its contributors 1824424Swosch * may be used to endorse or promote products derived from this software 1942704Swosch * without specific prior written permission. 2042704Swosch * 2142704Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2242704Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2342704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2442704Swosch * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2542704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2642704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2742704Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2842704Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2942704Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059769Sgrog * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159769Sgrog * SUCH DAMAGE. 3259769Sgrog */ 3359769Sgrog 3459769Sgrog#ifndef lint 3559769Sgrogstatic char sccsid[] = "@(#)displayq.c 8.1 (Berkeley) 6/6/93"; 3659769Sgrog#endif /* not lint */ 3759769Sgrog 3859769Sgrog#include <sys/param.h> 3924424Swosch#include <sys/stat.h> 4042704Swosch 4124424Swosch#include <signal.h> 4242704Swosch#include <fcntl.h> 4324424Swosch#include <dirent.h> 4442704Swosch#include <unistd.h> 4524424Swosch#include <stdio.h> 4624424Swosch#include <stdlib.h> 4724424Swosch#include <string.h> 4842704Swosch#include <ctype.h> 4925031Swosch#include "lp.h" 5059156Swosch#include "lp.local.h" 5125031Swosch#include "pathnames.h" 5225031Swosch 5324424Swosch/* 5424424Swosch * Routines to display the state of the queue. 5524424Swosch */ 5624424Swosch#define JOBCOL 40 /* column for job # in -l format */ 5771231Sitojun#define OWNCOL 7 /* start of Owner column in normal */ 5824424Swosch#define SIZCOL 62 /* start of Size column in normal */ 5971231Sitojun 6025031Swosch/* 6171231Sitojun * Stuff for handling job specifications 6224424Swosch */ 6325031Swoschextern int requ[]; /* job number of spool entries */ 6425031Swoschextern int requests; /* # of spool requests */ 6571231Sitojunextern char *user[]; /* users to process */ 6625031Swoschextern int users; /* # of users in user array */ 6771231Sitojun 6870110Swoschstatic int col; /* column on screen */ 6970110Swoschstatic char current[40]; /* current file being printed */ 7070110Swoschstatic char file[132]; /* print file name */ 7170110Swoschstatic int first; /* first file in ``files'' column? */ 7270110Swoschstatic int garbage; /* # of garbage cf files */ 7370110Swoschstatic int lflag; /* long output option */ 7470110Swoschstatic int rank; /* order to be printed (-1=none, 0=active) */ 7570110Swoschstatic long totsize; /* total print job size in bytes */ 7670110Swosch 7770110Swoschstatic char *head0 = "Rank Owner Job Files"; 7870110Swoschstatic char *head1 = "Total Size\n"; 7980675Sasmodai 8080675Sasmodai/* 8180675Sasmodai * Display the current state of the queue. Format = 1 if long format. 8280675Sasmodai */ 8380675Sasmodaivoid 8480675Sasmodaidisplayq(format) 8580675Sasmodai int format; 8680675Sasmodai{ 8780675Sasmodai register struct queue *q; 8880675Sasmodai register int i, nitems, fd; 8980675Sasmodai register char *cp; 9080675Sasmodai struct queue **queue; 9180675Sasmodai struct stat statb; 9280675Sasmodai FILE *fp; 9380675Sasmodai 9480675Sasmodai lflag = format; 9580675Sasmodai totsize = 0; 9680675Sasmodai rank = -1; 9780675Sasmodai if ((i = cgetent(&bp, printcapdb, printer)) == -2) 9880675Sasmodai fatal("can't open printer description file"); 9980675Sasmodai else if (i == -1) 10080675Sasmodai fatal("unknown printer"); 10180675Sasmodai else if (i == -3) 10280675Sasmodai fatal("potential reference loop detected in printcap file"); 10380675Sasmodai if (cgetstr(bp, "lp", &LP) < 0) 10480675Sasmodai LP = _PATH_DEFDEVLP; 10580675Sasmodai if (cgetstr(bp, "rp", &RP) < 0) 10680675Sasmodai RP = DEFLP; 10780675Sasmodai if (cgetstr(bp, "sd", &SD) < 0) 10880675Sasmodai SD = _PATH_DEFSPOOL; 10980675Sasmodai if (cgetstr(bp,"lo", &LO) < 0) 11080675Sasmodai LO = DEFLOCK; 11180675Sasmodai if (cgetstr(bp, "st", &ST) < 0) 11280675Sasmodai ST = DEFSTAT; 11380675Sasmodai cgetstr(bp, "rm", &RM); 11480675Sasmodai if (cp = checkremote()) 11580675Sasmodai printf("Warning: %s\n", cp); 11680675Sasmodai 11780675Sasmodai /* 11880675Sasmodai * Print out local queue 11980675Sasmodai * Find all the control files in the spooling directory 12080675Sasmodai */ 12180675Sasmodai if (chdir(SD) < 0) 12280675Sasmodai fatal("cannot chdir to spooling directory"); 12380675Sasmodai if ((nitems = getq(&queue)) < 0) 12480675Sasmodai fatal("cannot examine spooling area\n"); 12580675Sasmodai if (stat(LO, &statb) >= 0) { 12680675Sasmodai if (statb.st_mode & 0100) { 12780675Sasmodai if (sendtorem) 12880675Sasmodai printf("%s: ", host); 12980675Sasmodai printf("Warning: %s is down: ", printer); 13080675Sasmodai fd = open(ST, O_RDONLY); 13180675Sasmodai if (fd >= 0) { 13280675Sasmodai (void) flock(fd, LOCK_SH); 13380675Sasmodai while ((i = read(fd, line, sizeof(line))) > 0) 13480675Sasmodai (void) fwrite(line, 1, i, stdout); 13580675Sasmodai (void) close(fd); /* unlocks as well */ 13680675Sasmodai } else 13780675Sasmodai putchar('\n'); 138101401Swosch } 13980675Sasmodai if (statb.st_mode & 010) { 14087200Swosch if (sendtorem) 14187200Swosch printf("%s: ", host); 14287200Swosch printf("Warning: %s queue is turned off\n", printer); 14380675Sasmodai } 144104772Smaxim } 145104772Smaxim 146104772Smaxim if (nitems) { 147104772Smaxim fp = fopen(LO, "r"); 148104781Sjhb if (fp == NULL) 149104781Sjhb warn(); 150104781Sjhb else { 151104781Sjhb /* get daemon pid */ 152104781Sjhb cp = current; 153104781Sjhb while ((*cp = getc(fp)) != EOF && *cp != '\n') 154104781Sjhb cp++; 155113054Smurray *cp = '\0'; 156113054Smurray i = atoi(current); 157113054Smurray if (i <= 0 || kill(i, 0) < 0) 158114211Swosch warn(); 159114211Swosch else { 160114211Swosch /* read current file name */ 161114211Swosch cp = current; 162114211Swosch while ((*cp = getc(fp)) != EOF && *cp != '\n') 163111949Swosch cp++; 164111949Swosch *cp = '\0'; 16580675Sasmodai /* 16680675Sasmodai * Print the status file. 167104781Sjhb */ 16824424Swosch if (sendtorem) 16924424Swosch printf("%s: ", host); 17024424Swosch fd = open(ST, O_RDONLY); 17124424Swosch if (fd >= 0) { 17269277Sasmodai (void) flock(fd, LOCK_SH); 17369277Sasmodai while ((i = read(fd, line, sizeof(line))) > 0) 17424424Swosch (void) fwrite(line, 1, i, stdout); 17525031Swosch (void) close(fd); /* unlocks as well */ 17625031Swosch } else 17725031Swosch putchar('\n'); 17880675Sasmodai } 179104782Sjhb (void) fclose(fp); 18025031Swosch } 181104782Sjhb /* 182104782Sjhb * Now, examine the control files and print out the jobs to 183104782Sjhb * be done for each user. 184104797Sjhb */ 185104797Sjhb if (!lflag) 18625031Swosch header(); 18725031Swosch for (i = 0; i < nitems; i++) { 18825031Swosch q = queue[i]; 18945349Swosch inform(q->q_name); 19045349Swosch free(q); 191104782Sjhb } 192104782Sjhb free(queue); 193104782Sjhb } 194104782Sjhb if (!sendtorem) { 19542704Swosch if (nitems == 0) 19625031Swosch puts("no entries"); 19724424Swosch return; 19859769Sgrog } 19925031Swosch 20025031Swosch /* 20125031Swosch * Print foreign queue 20225031Swosch * Note that a file in transit may show up in either queue. 20359769Sgrog */ 20425031Swosch if (nitems) 20525031Swosch putchar('\n'); 20625031Swosch (void) sprintf(line, "%c%s", format + '\3', RP); 20725031Swosch cp = line; 20824424Swosch for (i = 0; i < requests; i++) { 20925031Swosch cp += strlen(cp); 21025031Swosch (void) sprintf(cp, " %d", requ[i]); 21125031Swosch } 21225031Swosch for (i = 0; i < users; i++) { 21325031Swosch cp += strlen(cp); 21459769Sgrog *cp++ = ' '; 21559769Sgrog (void) strcpy(cp, user[i]); 21642704Swosch } 21742704Swosch strcat(line, "\n"); 21842704Swosch fd = getport(RM); 21970110Swosch if (fd < 0) { 22042704Swosch if (from != host) 22142704Swosch printf("%s: ", host); 22225031Swosch printf("connection to %s is down\n", RM); 22325031Swosch } 22424424Swosch else { 22525031Swosch i = strlen(line); 22625031Swosch if (write(fd, line, i) != i) 22725031Swosch fatal("Lost connection"); 22825031Swosch while ((i = read(fd, line, sizeof(line))) > 0) 22925031Swosch (void) fwrite(line, 1, i, stdout); 23025031Swosch (void) close(fd); 23125031Swosch } 23225031Swosch} 23325031Swosch 23424424Swosch/* 23525031Swosch * Print a warning message if there is no daemon present. 23625031Swosch */ 23725031Swoschvoid 23825031Swoschwarn() 23925031Swosch{ 24025031Swosch if (sendtorem) 24125031Swosch printf("\n%s: ", host); 24225031Swosch puts("Warning: no daemon present"); 24359156Swosch current[0] = '\0'; 24425031Swosch} 24525031Swosch 24625031Swosch/* 24725031Swosch * Print the header for the short listing format 24825031Swosch */ 24925031Swoschvoid 25089981Sjoeheader() 25125031Swosch{ 25225031Swosch printf(head0); 25325031Swosch col = strlen(head0)+1; 25424424Swosch blankfill(SIZCOL); 25525031Swosch printf(head1); 25625031Swosch} 25789981Sjoe 25825031Swoschvoid 25989981Sjoeinform(cf) 26089981Sjoe char *cf; 26125031Swosch{ 26289981Sjoe register int j; 26389981Sjoe FILE *cfp; 26489981Sjoe 26570110Swosch /* 26671231Sitojun * There's a chance the control file has gone away 26770110Swosch * in the meantime; if this is the case just keep going 26825031Swosch */ 26971231Sitojun if ((cfp = fopen(cf, "r")) == NULL) 27071231Sitojun return; 27169278Sasmodai 27225031Swosch if (rank < 0) 27371231Sitojun rank = 0; 27470110Swosch if (sendtorem || garbage || strcmp(cf, current)) 27571231Sitojun rank++; 27670110Swosch j = 0; 27770110Swosch while (getline(cfp)) { 27871231Sitojun switch (line[0]) { 27970110Swosch case 'P': /* Was this file specified in the user's list? */ 28057000Swosch if (!inlist(line+1, cf)) { 28125031Swosch fclose(cfp); 28245349Swosch return; 28378270Snik } 28471231Sitojun if (lflag) { 28525031Swosch printf("\n%s: ", line+1); 28638440Sjkh col = strlen(line+1) + 2; 28738440Sjkh prank(rank); 28849392Swosch blankfill(JOBCOL); 28957000Swosch printf(" [job %s]\n", cf+3); 29038440Sjkh } else { 29138440Sjkh col = 0; 29270110Swosch prank(rank); 29369278Sasmodai blankfill(OWNCOL); 29470110Swosch printf("%-10s %-3d ", line+1, atoi(cf+3)); 29525031Swosch col += 16; 29625031Swosch first = 1; 29769278Sasmodai } 29845349Swosch continue; 29970110Swosch default: /* some format specifer and file name? */ 30069278Sasmodai if (line[0] < 'a' || line[0] > 'z') 30145349Swosch continue; 30245349Swosch if (j == 0 || strcmp(file, line+1) != 0) 30369278Sasmodai (void) strcpy(file, line+1); 30469278Sasmodai j++; 30580675Sasmodai continue; 30669278Sasmodai case 'N': 30770110Swosch show(line+1, file, j); 30869278Sasmodai file[0] = '\0'; 30969278Sasmodai j = 0; 31069278Sasmodai } 31157000Swosch } 31245349Swosch fclose(cfp); 31369277Sasmodai if (!lflag) { 31445349Swosch blankfill(SIZCOL); 31566542Sitojun printf("%ld bytes\n", totsize); 31669277Sasmodai totsize = 0; 31757000Swosch } 31870110Swosch} 31945349Swosch 32057000Swoschint 32169277Sasmodaiinlist(name, file) 32270110Swosch char *name, *file; 32370110Swosch{ 32442589Swosch register int *r, n; 32570110Swosch register char **u, *cp; 32670110Swosch 32746321Swosch if (users == 0 && requests == 0) 32845349Swosch return(1); 32945349Swosch /* 33057000Swosch * Check to see if it's in the user list 33146318Swosch */ 33270110Swosch for (u = user; u < &user[users]; u++) 33356406Swosch if (!strcmp(*u, name)) 33455389Sbillf return(1); 33555389Sbillf /* 33657000Swosch * Check the request list 33755389Sbillf */ 33855389Sbillf for (n = 0, cp = file+3; isdigit(*cp); ) 33955389Sbillf n = n * 10 + (*cp++ - '0'); 34070110Swosch for (r = requ; r < &requ[requests]; r++) 34158448Swosch if (*r == n && !strcmp(cp, from)) 34258448Swosch return(1); 34365412Swosch return(0); 34464612Salex} 34564612Salex 34665411Swoschvoid 34765974Swoschshow(nfile, file, copies) 34869277Sasmodai register char *nfile, *file; 34969277Sasmodai int copies; 35070119Swosch{ 35169277Sasmodai if (strcmp(nfile, " ") == 0) 35270111Swosch nfile = "(standard input)"; 35380675Sasmodai if (lflag) 35475833Swosch ldump(nfile, file, copies); 35578867Sitojun else 35679603Sitojun dump(nfile, file, copies); 35784087Swosch} 35883686Sobrien 359104797Sjhb/* 36087201Swosch * Fill the line with blanks to the specified column 36192013Swosch */ 362104772Smaximvoid 363101331Swoschblankfill(n) 364101331Swosch register int n; 365104797Sjhb{ 366104781Sjhb while (col++ < n) 367104781Sjhb putchar(' '); 368104781Sjhb} 369104659Smurray 370106406Smaxim/* 371111949Swosch * Give the abbreviated dump of the file names 372111949Swosch */ 373111949Swoschvoid 374113054Smurraydump(nfile, file, copies) 375114211Swosch char *nfile, *file; 37624424Swosch int copies; 377111949Swosch{ 37824424Swosch register short n, fill; 37924424Swosch struct stat lbuf; 38024424Swosch 38124424Swosch /* 38224424Swosch * Print as many files as will fit 38324424Swosch * (leaving room for the total size) 38424424Swosch */ 38524424Swosch fill = first ? 0 : 2; /* fill space for ``, '' */ 38624424Swosch if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 38724424Swosch if (col < SIZCOL) { 38824424Swosch printf(" ..."), col += 4; 38924424Swosch blankfill(SIZCOL); 39024424Swosch } 39124424Swosch } else { 39225031Swosch if (first) 39325031Swosch first = 0; 39424424Swosch else 39524424Swosch printf(", "); 39624424Swosch printf("%s", nfile); 39724424Swosch col += n+fill; 39859769Sgrog } 39979514Sitojun if (*file && !stat(file, &lbuf)) 40024424Swosch totsize += copies * lbuf.st_size; 40125031Swosch} 40225031Swosch 40325031Swosch/* 40425031Swosch * Print the long info about the file 40559769Sgrog */ 40625031Swoschvoid 40731658Swoschldump(nfile, file, copies) 40879514Sitojun char *nfile, *file; 40931658Swosch int copies; 41059769Sgrog{ 41179514Sitojun struct stat lbuf; 41259769Sgrog 41365415Swosch putchar('\t'); 414104786Sjhb if (copies > 1) 41565415Swosch printf("%-2d copies of %-19s", copies, nfile); 41675834Swosch else 41779514Sitojun printf("%-32s", nfile); 41875834Swosch if (*file && !stat(file, &lbuf)) 41975834Swosch printf(" %qd bytes", lbuf.st_size); 42075834Swosch else 42125031Swosch printf(" ??? bytes"); 42225031Swosch putchar('\n'); 42325031Swosch} 42459769Sgrog 42525031Swosch/* 42625031Swosch * Print the job's rank in the queue, 42731658Swosch * update col for screen management 42825031Swosch */ 42924424Swoschvoid 43072877Swoschprank(n) 43167388Swosch int n; 43242589Swosch{ 43350970Speter char rline[100]; 434 static char *r[] = { 435 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 436 }; 437 438 if (n == 0) { 439 printf("active"); 440 col += 6; 441 return; 442 } 443 if ((n/10)%10 == 1) 444 (void)snprintf(rline, sizeof(rline), "%dth", n); 445 else 446 (void)snprintf(rline, sizeof(rline), "%d%s", n, r[n%10]); 447 col += strlen(rline); 448 printf("%s", rline); 449} 450