122427Sdist /* 222427Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 534203Sbostic * Redistribution and use in source and binary forms are permitted 634936Sbostic * provided that the above copyright notice and this paragraph are 734936Sbostic * duplicated in all such forms and that any documentation, 834936Sbostic * advertising materials, and other materials related to such 934936Sbostic * distribution and use acknowledge that the software was developed 1034936Sbostic * by the University of California, Berkeley. The name of the 1134936Sbostic * University may not be used to endorse or promote products derived 1234936Sbostic * from this software without specific prior written permission. 1334936Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434936Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534936Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622427Sdist */ 1722427Sdist 1813952Ssam #ifndef lint 19*38491Sbostic static char sccsid[] = "@(#)displayq.c 5.10 (Berkeley) 07/27/89"; 2034203Sbostic #endif /* not lint */ 2113952Ssam 2212113Sralph /* 2312113Sralph * Routines to display the state of the queue. 2412113Sralph */ 2512113Sralph 2612113Sralph #include "lp.h" 2737968Sbostic #include "pathnames.h" 2812113Sralph 2913170Sralph #define JOBCOL 40 /* column for job # in -l format */ 3013170Sralph #define OWNCOL 7 /* start of Owner column in normal */ 3113170Sralph #define SIZCOL 62 /* start of Size column in normal */ 3212113Sralph 3312113Sralph /* 3412113Sralph * Stuff for handling job specifications 3512113Sralph */ 3612113Sralph extern char *user[]; /* users to process */ 3712113Sralph extern int users; /* # of users in user array */ 3812113Sralph extern int requ[]; /* job number of spool entries */ 3912113Sralph extern int requests; /* # of spool requests */ 4012113Sralph 4116758Sralph int lflag; /* long output option */ 4216758Sralph char current[40]; /* current file being printed */ 4316758Sralph int garbage; /* # of garbage cf files */ 4416758Sralph int rank; /* order to be printed (-1=none, 0=active) */ 4516758Sralph long totsize; /* total print job size in bytes */ 4616758Sralph int first; /* first file in ``files'' column? */ 4716758Sralph int col; /* column on screen */ 4816758Sralph int sendtorem; /* are we sending to a remote? */ 4916758Sralph char file[132]; /* print file name */ 5012113Sralph 5116758Sralph char *head0 = "Rank Owner Job Files"; 5216758Sralph char *head1 = "Total Size\n"; 5312113Sralph 5412113Sralph /* 5512113Sralph * Display the current state of the queue. Format = 1 if long format. 5612113Sralph */ 5712113Sralph displayq(format) 5812113Sralph int format; 5912113Sralph { 6012113Sralph register struct queue *q; 6112113Sralph register int i, nitems, fd; 6230995Sbostic register char *cp; 6312113Sralph struct queue **queue; 6412113Sralph struct stat statb; 6512113Sralph FILE *fp; 6630995Sbostic char c; 6712113Sralph 6812113Sralph lflag = format; 6912113Sralph totsize = 0; 7012113Sralph rank = -1; 7112113Sralph 7212113Sralph if ((i = pgetent(line, printer)) < 0) 7312113Sralph fatal("cannot open printer description file"); 7412113Sralph else if (i == 0) 7512113Sralph fatal("unknown printer"); 7612113Sralph if ((LP = pgetstr("lp", &bp)) == NULL) 7737968Sbostic LP = _PATH_DEFDEVLP; 7812113Sralph if ((RP = pgetstr("rp", &bp)) == NULL) 7912434Sralph RP = DEFLP; 8012113Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 8137968Sbostic SD = _PATH_DEFSPOOL; 8212113Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 8312113Sralph LO = DEFLOCK; 8412113Sralph if ((ST = pgetstr("st", &bp)) == NULL) 8512113Sralph ST = DEFSTAT; 8612113Sralph RM = pgetstr("rm", &bp); 8712113Sralph 8812113Sralph /* 8925467Stef * Figure out whether the local machine is the same as the remote 9025467Stef * machine entry (if it exists). If not, then ignore the local 9125467Stef * queue information. 9225467Stef */ 9325467Stef if (RM != (char *) NULL) { 9425467Stef char name[256]; 9525467Stef struct hostent *hp; 9625467Stef 9725467Stef /* get the standard network name of the local host */ 9825467Stef gethostname(name, sizeof(name)); 9925467Stef name[sizeof(name)-1] = '\0'; 10025467Stef hp = gethostbyname(name); 10125467Stef if (hp == (struct hostent *) NULL) { 10225467Stef printf("unable to get network name for local machine %s\n", 10325467Stef name); 10425467Stef goto localcheck_done; 10530995Sbostic } else (void) strcpy(name, hp->h_name); 10625467Stef 10725467Stef /* get the network standard name of RM */ 10825467Stef hp = gethostbyname(RM); 10925467Stef if (hp == (struct hostent *) NULL) { 11025467Stef printf("unable to get hostname for remote machine %s\n", 11125467Stef RM); 11225467Stef goto localcheck_done; 11325467Stef } 11425467Stef 11525467Stef /* if printer is not on local machine, ignore LP */ 11630995Sbostic if (strcmp(name, hp->h_name)) { 11730995Sbostic *LP = '\0'; 11830995Sbostic ++sendtorem; 11930995Sbostic } 12025467Stef } 12125467Stef localcheck_done: 12225467Stef 12325467Stef /* 12430995Sbostic * Print out local queue 12512113Sralph * Find all the control files in the spooling directory 12612113Sralph */ 12712113Sralph if (chdir(SD) < 0) 12812113Sralph fatal("cannot chdir to spooling directory"); 12912113Sralph if ((nitems = getq(&queue)) < 0) 13012113Sralph fatal("cannot examine spooling area\n"); 13116205Sralph if (stat(LO, &statb) >= 0) { 13216205Sralph if (statb.st_mode & 0100) { 13316205Sralph if (sendtorem) 13416205Sralph printf("%s: ", host); 13516205Sralph printf("Warning: %s is down: ", printer); 13616205Sralph fd = open(ST, O_RDONLY); 13716205Sralph if (fd >= 0) { 13816205Sralph (void) flock(fd, LOCK_SH); 13916205Sralph while ((i = read(fd, line, sizeof(line))) > 0) 14016205Sralph (void) fwrite(line, 1, i, stdout); 14116205Sralph (void) close(fd); /* unlocks as well */ 14216205Sralph } else 14316205Sralph putchar('\n'); 14416205Sralph } 14516205Sralph if (statb.st_mode & 010) { 14616205Sralph if (sendtorem) 14716205Sralph printf("%s: ", host); 14816205Sralph printf("Warning: %s queue is turned off\n", printer); 14916205Sralph } 15012740Sralph } 15112113Sralph 15230995Sbostic if (nitems) { 15330995Sbostic fp = fopen(LO, "r"); 15430995Sbostic if (fp == NULL) 15513441Sralph warn(); 15613441Sralph else { 15730995Sbostic register char *cp; 15830995Sbostic 15930995Sbostic /* get daemon pid */ 16013441Sralph cp = current; 16113441Sralph while ((*cp = getc(fp)) != EOF && *cp != '\n') 16213441Sralph cp++; 16313441Sralph *cp = '\0'; 16430995Sbostic i = atoi(current); 16530995Sbostic if (i <= 0 || kill(i, 0) < 0) 16630995Sbostic warn(); 16730995Sbostic else { 16830995Sbostic /* read current file name */ 16930995Sbostic cp = current; 17030995Sbostic while ((*cp = getc(fp)) != EOF && *cp != '\n') 17130995Sbostic cp++; 17230995Sbostic *cp = '\0'; 17330995Sbostic /* 17430995Sbostic * Print the status file. 17530995Sbostic */ 17630995Sbostic if (sendtorem) 17730995Sbostic printf("%s: ", host); 17830995Sbostic fd = open(ST, O_RDONLY); 17930995Sbostic if (fd >= 0) { 18030995Sbostic (void) flock(fd, LOCK_SH); 18130995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 18230995Sbostic (void) fwrite(line, 1, i, stdout); 18330995Sbostic (void) close(fd); /* unlocks as well */ 18430995Sbostic } else 18530995Sbostic putchar('\n'); 18630995Sbostic } 18730995Sbostic (void) fclose(fp); 18813441Sralph } 18930995Sbostic /* 19030995Sbostic * Now, examine the control files and print out the jobs to 19130995Sbostic * be done for each user. 19230995Sbostic */ 19330995Sbostic if (!lflag) 19430995Sbostic header(); 19530995Sbostic for (i = 0; i < nitems; i++) { 19630995Sbostic q = queue[i]; 19730995Sbostic inform(q->q_name); 19830995Sbostic free(q); 19930995Sbostic } 20030995Sbostic free(queue); 20112113Sralph } 20231678Skarels if (!sendtorem) { 20331678Skarels if (nitems == 0) 20431678Skarels puts("no entries"); 20530995Sbostic return; 20630995Sbostic } 20730995Sbostic 20812113Sralph /* 20930995Sbostic * Print foreign queue 21030995Sbostic * Note that a file in transit may show up in either queue. 21112113Sralph */ 21230995Sbostic if (nitems) 21330995Sbostic putchar('\n'); 21430995Sbostic (void) sprintf(line, "%c%s", format + '\3', RP); 21530995Sbostic cp = line; 21630995Sbostic for (i = 0; i < requests; i++) { 21730995Sbostic cp += strlen(cp); 21830995Sbostic (void) sprintf(cp, " %d", requ[i]); 21912113Sralph } 22030995Sbostic for (i = 0; i < users; i++) { 22130995Sbostic cp += strlen(cp); 22230995Sbostic *cp++ = ' '; 22330995Sbostic (void) strcpy(cp, user[i]); 22430995Sbostic } 22530995Sbostic strcat(line, "\n"); 22630995Sbostic fd = getport(RM); 22730995Sbostic if (fd < 0) { 22830995Sbostic if (from != host) 22930995Sbostic printf("%s: ", host); 23030995Sbostic printf("connection to %s is down\n", RM); 23130995Sbostic } 23230995Sbostic else { 23330995Sbostic i = strlen(line); 23430995Sbostic if (write(fd, line, i) != i) 23530995Sbostic fatal("Lost connection"); 23630995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 23730995Sbostic (void) fwrite(line, 1, i, stdout); 23830995Sbostic (void) close(fd); 23930995Sbostic } 24012113Sralph } 24112113Sralph 24212113Sralph /* 24313441Sralph * Print a warning message if there is no daemon present. 24413441Sralph */ 24513441Sralph warn() 24613441Sralph { 24713441Sralph if (sendtorem) 24813441Sralph printf("\n%s: ", host); 24930995Sbostic puts("Warning: no daemon present"); 25013441Sralph current[0] = '\0'; 25113441Sralph } 25213441Sralph 25313441Sralph /* 25412113Sralph * Print the header for the short listing format 25512113Sralph */ 25612113Sralph header() 25712113Sralph { 25812113Sralph printf(head0); 25912113Sralph col = strlen(head0)+1; 26012113Sralph blankfill(SIZCOL); 26112113Sralph printf(head1); 26212113Sralph } 26312113Sralph 26412113Sralph inform(cf) 26512113Sralph char *cf; 26612113Sralph { 26712113Sralph register int j, k; 26812113Sralph register char *cp; 26912113Sralph FILE *cfp; 27012113Sralph 27112113Sralph /* 27212113Sralph * There's a chance the control file has gone away 27312113Sralph * in the meantime; if this is the case just keep going 27412113Sralph */ 27512113Sralph if ((cfp = fopen(cf, "r")) == NULL) 27612113Sralph return; 27712113Sralph 27812113Sralph if (rank < 0) 27912113Sralph rank = 0; 28012113Sralph if (sendtorem || garbage || strcmp(cf, current)) 28112113Sralph rank++; 28212113Sralph j = 0; 28312113Sralph while (getline(cfp)) { 28412113Sralph switch (line[0]) { 28512113Sralph case 'P': /* Was this file specified in the user's list? */ 28612113Sralph if (!inlist(line+1, cf)) { 28712113Sralph fclose(cfp); 28812113Sralph return; 28912113Sralph } 29012113Sralph if (lflag) { 29112113Sralph printf("\n%s: ", line+1); 29212113Sralph col = strlen(line+1) + 2; 29312113Sralph prank(rank); 29412113Sralph blankfill(JOBCOL); 29512113Sralph printf(" [job %s]\n", cf+3); 29612113Sralph } else { 29712113Sralph col = 0; 29812113Sralph prank(rank); 29912113Sralph blankfill(OWNCOL); 30012113Sralph printf("%-10s %-3d ", line+1, atoi(cf+3)); 30112113Sralph col += 16; 30212113Sralph first = 1; 30312113Sralph } 30412113Sralph continue; 30512113Sralph default: /* some format specifer and file name? */ 30612113Sralph if (line[0] < 'a' || line[0] > 'z') 30712113Sralph continue; 30812113Sralph if (j == 0 || strcmp(file, line+1) != 0) 30930995Sbostic (void) strcpy(file, line+1); 31012113Sralph j++; 31112113Sralph continue; 31212113Sralph case 'N': 31312113Sralph show(line+1, file, j); 31412113Sralph file[0] = '\0'; 31512113Sralph j = 0; 31612113Sralph } 31712113Sralph } 31812113Sralph fclose(cfp); 31912113Sralph if (!lflag) { 32012113Sralph blankfill(SIZCOL); 32134587Sbostic printf("%ld bytes\n", totsize); 32212113Sralph totsize = 0; 32312113Sralph } 32412113Sralph } 32512113Sralph 32612113Sralph inlist(name, file) 32712113Sralph char *name, *file; 32812113Sralph { 32912113Sralph register int *r, n; 33012113Sralph register char **u, *cp; 33112113Sralph 33212113Sralph if (users == 0 && requests == 0) 33312113Sralph return(1); 33412113Sralph /* 33512113Sralph * Check to see if it's in the user list 33612113Sralph */ 33712113Sralph for (u = user; u < &user[users]; u++) 33812113Sralph if (!strcmp(*u, name)) 33912113Sralph return(1); 34012113Sralph /* 34112113Sralph * Check the request list 34212113Sralph */ 34312113Sralph for (n = 0, cp = file+3; isdigit(*cp); ) 34412113Sralph n = n * 10 + (*cp++ - '0'); 34512113Sralph for (r = requ; r < &requ[requests]; r++) 34612113Sralph if (*r == n && !strcmp(cp, from)) 34712113Sralph return(1); 34812113Sralph return(0); 34912113Sralph } 35012113Sralph 35112113Sralph show(nfile, file, copies) 35212113Sralph register char *nfile, *file; 35312113Sralph { 35412113Sralph if (strcmp(nfile, " ") == 0) 35512113Sralph nfile = "(standard input)"; 35612113Sralph if (lflag) 35712113Sralph ldump(nfile, file, copies); 35812113Sralph else 35912113Sralph dump(nfile, file, copies); 36012113Sralph } 36112113Sralph 36212113Sralph /* 36312113Sralph * Fill the line with blanks to the specified column 36412113Sralph */ 36512113Sralph blankfill(n) 36612113Sralph register int n; 36712113Sralph { 36812113Sralph while (col++ < n) 36912113Sralph putchar(' '); 37012113Sralph } 37112113Sralph 37212113Sralph /* 37312113Sralph * Give the abbreviated dump of the file names 37412113Sralph */ 37512113Sralph dump(nfile, file, copies) 37612113Sralph char *nfile, *file; 37712113Sralph { 37812113Sralph register short n, fill; 37912113Sralph struct stat lbuf; 38012113Sralph 38112113Sralph /* 38212113Sralph * Print as many files as will fit 38312113Sralph * (leaving room for the total size) 38412113Sralph */ 38512113Sralph fill = first ? 0 : 2; /* fill space for ``, '' */ 38612113Sralph if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 38712113Sralph if (col < SIZCOL) { 38812113Sralph printf(" ..."), col += 4; 38912113Sralph blankfill(SIZCOL); 39012113Sralph } 39112113Sralph } else { 39212113Sralph if (first) 39312113Sralph first = 0; 39412113Sralph else 39512113Sralph printf(", "); 39612113Sralph printf("%s", nfile); 39712113Sralph col += n+fill; 39812113Sralph } 39912113Sralph if (*file && !stat(file, &lbuf)) 40012113Sralph totsize += copies * lbuf.st_size; 40112113Sralph } 40212113Sralph 40312113Sralph /* 40412113Sralph * Print the long info about the file 40512113Sralph */ 40612113Sralph ldump(nfile, file, copies) 40712113Sralph char *nfile, *file; 40812113Sralph { 40912113Sralph struct stat lbuf; 41012113Sralph 41112113Sralph putchar('\t'); 41212113Sralph if (copies > 1) 41312113Sralph printf("%-2d copies of %-19s", copies, nfile); 41412113Sralph else 41512113Sralph printf("%-32s", nfile); 41612113Sralph if (*file && !stat(file, &lbuf)) 41734587Sbostic printf(" %ld bytes", lbuf.st_size); 41812113Sralph else 41912113Sralph printf(" ??? bytes"); 42012113Sralph putchar('\n'); 42112113Sralph } 42212113Sralph 42312113Sralph /* 42412113Sralph * Print the job's rank in the queue, 42512113Sralph * update col for screen management 42612113Sralph */ 42712113Sralph prank(n) 42812113Sralph { 42912113Sralph char line[100]; 43012113Sralph static char *r[] = { 43112113Sralph "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 43212113Sralph }; 43312113Sralph 43412113Sralph if (n == 0) { 43512113Sralph printf("active"); 43612113Sralph col += 6; 43712113Sralph return; 43812113Sralph } 439*38491Sbostic if ((n/10)%10 == 1) 44012113Sralph (void) sprintf(line, "%dth", n); 44112113Sralph else 44212113Sralph (void) sprintf(line, "%d%s", n, r[n%10]); 44312113Sralph col += strlen(line); 44412113Sralph printf("%s", line); 44512113Sralph } 446