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 634203Sbostic * provided that this notice is preserved and that due credit is given 734203Sbostic * to the University of California at Berkeley. The name of the University 834203Sbostic * may not be used to endorse or promote products derived from this 934203Sbostic * software without specific prior written permission. This software 1034203Sbostic * is provided ``as is'' without express or implied warranty. 1122427Sdist */ 1222427Sdist 1313952Ssam #ifndef lint 14*34587Sbostic static char sccsid[] = "@(#)displayq.c 5.7 (Berkeley) 06/01/88"; 1534203Sbostic #endif /* not lint */ 1613952Ssam 1712113Sralph /* 1812113Sralph * Routines to display the state of the queue. 1912113Sralph */ 2012113Sralph 2112113Sralph #include "lp.h" 2212113Sralph 2313170Sralph #define JOBCOL 40 /* column for job # in -l format */ 2413170Sralph #define OWNCOL 7 /* start of Owner column in normal */ 2513170Sralph #define SIZCOL 62 /* start of Size column in normal */ 2612113Sralph 2712113Sralph /* 2812113Sralph * Stuff for handling job specifications 2912113Sralph */ 3012113Sralph extern char *user[]; /* users to process */ 3112113Sralph extern int users; /* # of users in user array */ 3212113Sralph extern int requ[]; /* job number of spool entries */ 3312113Sralph extern int requests; /* # of spool requests */ 3412113Sralph 3516758Sralph int lflag; /* long output option */ 3616758Sralph char current[40]; /* current file being printed */ 3716758Sralph int garbage; /* # of garbage cf files */ 3816758Sralph int rank; /* order to be printed (-1=none, 0=active) */ 3916758Sralph long totsize; /* total print job size in bytes */ 4016758Sralph int first; /* first file in ``files'' column? */ 4116758Sralph int col; /* column on screen */ 4216758Sralph int sendtorem; /* are we sending to a remote? */ 4316758Sralph char file[132]; /* print file name */ 4412113Sralph 4516758Sralph char *head0 = "Rank Owner Job Files"; 4616758Sralph char *head1 = "Total Size\n"; 4712113Sralph 4812113Sralph /* 4912113Sralph * Display the current state of the queue. Format = 1 if long format. 5012113Sralph */ 5112113Sralph displayq(format) 5212113Sralph int format; 5312113Sralph { 5412113Sralph register struct queue *q; 5512113Sralph register int i, nitems, fd; 5630995Sbostic register char *cp; 5712113Sralph struct queue **queue; 5812113Sralph struct stat statb; 5912113Sralph FILE *fp; 6030995Sbostic char c; 6112113Sralph 6212113Sralph lflag = format; 6312113Sralph totsize = 0; 6412113Sralph rank = -1; 6512113Sralph 6612113Sralph if ((i = pgetent(line, printer)) < 0) 6712113Sralph fatal("cannot open printer description file"); 6812113Sralph else if (i == 0) 6912113Sralph fatal("unknown printer"); 7012113Sralph if ((LP = pgetstr("lp", &bp)) == NULL) 7112113Sralph LP = DEFDEVLP; 7212113Sralph if ((RP = pgetstr("rp", &bp)) == NULL) 7312434Sralph RP = DEFLP; 7412113Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 7512113Sralph SD = DEFSPOOL; 7612113Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 7712113Sralph LO = DEFLOCK; 7812113Sralph if ((ST = pgetstr("st", &bp)) == NULL) 7912113Sralph ST = DEFSTAT; 8012113Sralph RM = pgetstr("rm", &bp); 8112113Sralph 8212113Sralph /* 8325467Stef * Figure out whether the local machine is the same as the remote 8425467Stef * machine entry (if it exists). If not, then ignore the local 8525467Stef * queue information. 8625467Stef */ 8725467Stef if (RM != (char *) NULL) { 8825467Stef char name[256]; 8925467Stef struct hostent *hp; 9025467Stef 9125467Stef /* get the standard network name of the local host */ 9225467Stef gethostname(name, sizeof(name)); 9325467Stef name[sizeof(name)-1] = '\0'; 9425467Stef hp = gethostbyname(name); 9525467Stef if (hp == (struct hostent *) NULL) { 9625467Stef printf("unable to get network name for local machine %s\n", 9725467Stef name); 9825467Stef goto localcheck_done; 9930995Sbostic } else (void) strcpy(name, hp->h_name); 10025467Stef 10125467Stef /* get the network standard name of RM */ 10225467Stef hp = gethostbyname(RM); 10325467Stef if (hp == (struct hostent *) NULL) { 10425467Stef printf("unable to get hostname for remote machine %s\n", 10525467Stef RM); 10625467Stef goto localcheck_done; 10725467Stef } 10825467Stef 10925467Stef /* if printer is not on local machine, ignore LP */ 11030995Sbostic if (strcmp(name, hp->h_name)) { 11130995Sbostic *LP = '\0'; 11230995Sbostic ++sendtorem; 11330995Sbostic } 11425467Stef } 11525467Stef localcheck_done: 11625467Stef 11725467Stef /* 11830995Sbostic * Print out local queue 11912113Sralph * Find all the control files in the spooling directory 12012113Sralph */ 12112113Sralph if (chdir(SD) < 0) 12212113Sralph fatal("cannot chdir to spooling directory"); 12312113Sralph if ((nitems = getq(&queue)) < 0) 12412113Sralph fatal("cannot examine spooling area\n"); 12516205Sralph if (stat(LO, &statb) >= 0) { 12616205Sralph if (statb.st_mode & 0100) { 12716205Sralph if (sendtorem) 12816205Sralph printf("%s: ", host); 12916205Sralph printf("Warning: %s is down: ", printer); 13016205Sralph fd = open(ST, O_RDONLY); 13116205Sralph if (fd >= 0) { 13216205Sralph (void) flock(fd, LOCK_SH); 13316205Sralph while ((i = read(fd, line, sizeof(line))) > 0) 13416205Sralph (void) fwrite(line, 1, i, stdout); 13516205Sralph (void) close(fd); /* unlocks as well */ 13616205Sralph } else 13716205Sralph putchar('\n'); 13816205Sralph } 13916205Sralph if (statb.st_mode & 010) { 14016205Sralph if (sendtorem) 14116205Sralph printf("%s: ", host); 14216205Sralph printf("Warning: %s queue is turned off\n", printer); 14316205Sralph } 14412740Sralph } 14512113Sralph 14630995Sbostic if (nitems) { 14730995Sbostic fp = fopen(LO, "r"); 14830995Sbostic if (fp == NULL) 14913441Sralph warn(); 15013441Sralph else { 15130995Sbostic register char *cp; 15230995Sbostic 15330995Sbostic /* get daemon pid */ 15413441Sralph cp = current; 15513441Sralph while ((*cp = getc(fp)) != EOF && *cp != '\n') 15613441Sralph cp++; 15713441Sralph *cp = '\0'; 15830995Sbostic i = atoi(current); 15930995Sbostic if (i <= 0 || kill(i, 0) < 0) 16030995Sbostic warn(); 16130995Sbostic else { 16230995Sbostic /* read current file name */ 16330995Sbostic cp = current; 16430995Sbostic while ((*cp = getc(fp)) != EOF && *cp != '\n') 16530995Sbostic cp++; 16630995Sbostic *cp = '\0'; 16730995Sbostic /* 16830995Sbostic * Print the status file. 16930995Sbostic */ 17030995Sbostic if (sendtorem) 17130995Sbostic printf("%s: ", host); 17230995Sbostic fd = open(ST, O_RDONLY); 17330995Sbostic if (fd >= 0) { 17430995Sbostic (void) flock(fd, LOCK_SH); 17530995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 17630995Sbostic (void) fwrite(line, 1, i, stdout); 17730995Sbostic (void) close(fd); /* unlocks as well */ 17830995Sbostic } else 17930995Sbostic putchar('\n'); 18030995Sbostic } 18130995Sbostic (void) fclose(fp); 18213441Sralph } 18330995Sbostic /* 18430995Sbostic * Now, examine the control files and print out the jobs to 18530995Sbostic * be done for each user. 18630995Sbostic */ 18730995Sbostic if (!lflag) 18830995Sbostic header(); 18930995Sbostic for (i = 0; i < nitems; i++) { 19030995Sbostic q = queue[i]; 19130995Sbostic inform(q->q_name); 19230995Sbostic free(q); 19330995Sbostic } 19430995Sbostic free(queue); 19512113Sralph } 19631678Skarels if (!sendtorem) { 19731678Skarels if (nitems == 0) 19831678Skarels puts("no entries"); 19930995Sbostic return; 20030995Sbostic } 20130995Sbostic 20212113Sralph /* 20330995Sbostic * Print foreign queue 20430995Sbostic * Note that a file in transit may show up in either queue. 20512113Sralph */ 20630995Sbostic if (nitems) 20730995Sbostic putchar('\n'); 20830995Sbostic (void) sprintf(line, "%c%s", format + '\3', RP); 20930995Sbostic cp = line; 21030995Sbostic for (i = 0; i < requests; i++) { 21130995Sbostic cp += strlen(cp); 21230995Sbostic (void) sprintf(cp, " %d", requ[i]); 21312113Sralph } 21430995Sbostic for (i = 0; i < users; i++) { 21530995Sbostic cp += strlen(cp); 21630995Sbostic *cp++ = ' '; 21730995Sbostic (void) strcpy(cp, user[i]); 21830995Sbostic } 21930995Sbostic strcat(line, "\n"); 22030995Sbostic fd = getport(RM); 22130995Sbostic if (fd < 0) { 22230995Sbostic if (from != host) 22330995Sbostic printf("%s: ", host); 22430995Sbostic printf("connection to %s is down\n", RM); 22530995Sbostic } 22630995Sbostic else { 22730995Sbostic i = strlen(line); 22830995Sbostic if (write(fd, line, i) != i) 22930995Sbostic fatal("Lost connection"); 23030995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 23130995Sbostic (void) fwrite(line, 1, i, stdout); 23230995Sbostic (void) close(fd); 23330995Sbostic } 23412113Sralph } 23512113Sralph 23612113Sralph /* 23713441Sralph * Print a warning message if there is no daemon present. 23813441Sralph */ 23913441Sralph warn() 24013441Sralph { 24113441Sralph if (sendtorem) 24213441Sralph printf("\n%s: ", host); 24330995Sbostic puts("Warning: no daemon present"); 24413441Sralph current[0] = '\0'; 24513441Sralph } 24613441Sralph 24713441Sralph /* 24812113Sralph * Print the header for the short listing format 24912113Sralph */ 25012113Sralph header() 25112113Sralph { 25212113Sralph printf(head0); 25312113Sralph col = strlen(head0)+1; 25412113Sralph blankfill(SIZCOL); 25512113Sralph printf(head1); 25612113Sralph } 25712113Sralph 25812113Sralph inform(cf) 25912113Sralph char *cf; 26012113Sralph { 26112113Sralph register int j, k; 26212113Sralph register char *cp; 26312113Sralph FILE *cfp; 26412113Sralph 26512113Sralph /* 26612113Sralph * There's a chance the control file has gone away 26712113Sralph * in the meantime; if this is the case just keep going 26812113Sralph */ 26912113Sralph if ((cfp = fopen(cf, "r")) == NULL) 27012113Sralph return; 27112113Sralph 27212113Sralph if (rank < 0) 27312113Sralph rank = 0; 27412113Sralph if (sendtorem || garbage || strcmp(cf, current)) 27512113Sralph rank++; 27612113Sralph j = 0; 27712113Sralph while (getline(cfp)) { 27812113Sralph switch (line[0]) { 27912113Sralph case 'P': /* Was this file specified in the user's list? */ 28012113Sralph if (!inlist(line+1, cf)) { 28112113Sralph fclose(cfp); 28212113Sralph return; 28312113Sralph } 28412113Sralph if (lflag) { 28512113Sralph printf("\n%s: ", line+1); 28612113Sralph col = strlen(line+1) + 2; 28712113Sralph prank(rank); 28812113Sralph blankfill(JOBCOL); 28912113Sralph printf(" [job %s]\n", cf+3); 29012113Sralph } else { 29112113Sralph col = 0; 29212113Sralph prank(rank); 29312113Sralph blankfill(OWNCOL); 29412113Sralph printf("%-10s %-3d ", line+1, atoi(cf+3)); 29512113Sralph col += 16; 29612113Sralph first = 1; 29712113Sralph } 29812113Sralph continue; 29912113Sralph default: /* some format specifer and file name? */ 30012113Sralph if (line[0] < 'a' || line[0] > 'z') 30112113Sralph continue; 30212113Sralph if (j == 0 || strcmp(file, line+1) != 0) 30330995Sbostic (void) strcpy(file, line+1); 30412113Sralph j++; 30512113Sralph continue; 30612113Sralph case 'N': 30712113Sralph show(line+1, file, j); 30812113Sralph file[0] = '\0'; 30912113Sralph j = 0; 31012113Sralph } 31112113Sralph } 31212113Sralph fclose(cfp); 31312113Sralph if (!lflag) { 31412113Sralph blankfill(SIZCOL); 315*34587Sbostic printf("%ld bytes\n", totsize); 31612113Sralph totsize = 0; 31712113Sralph } 31812113Sralph } 31912113Sralph 32012113Sralph inlist(name, file) 32112113Sralph char *name, *file; 32212113Sralph { 32312113Sralph register int *r, n; 32412113Sralph register char **u, *cp; 32512113Sralph 32612113Sralph if (users == 0 && requests == 0) 32712113Sralph return(1); 32812113Sralph /* 32912113Sralph * Check to see if it's in the user list 33012113Sralph */ 33112113Sralph for (u = user; u < &user[users]; u++) 33212113Sralph if (!strcmp(*u, name)) 33312113Sralph return(1); 33412113Sralph /* 33512113Sralph * Check the request list 33612113Sralph */ 33712113Sralph for (n = 0, cp = file+3; isdigit(*cp); ) 33812113Sralph n = n * 10 + (*cp++ - '0'); 33912113Sralph for (r = requ; r < &requ[requests]; r++) 34012113Sralph if (*r == n && !strcmp(cp, from)) 34112113Sralph return(1); 34212113Sralph return(0); 34312113Sralph } 34412113Sralph 34512113Sralph show(nfile, file, copies) 34612113Sralph register char *nfile, *file; 34712113Sralph { 34812113Sralph if (strcmp(nfile, " ") == 0) 34912113Sralph nfile = "(standard input)"; 35012113Sralph if (lflag) 35112113Sralph ldump(nfile, file, copies); 35212113Sralph else 35312113Sralph dump(nfile, file, copies); 35412113Sralph } 35512113Sralph 35612113Sralph /* 35712113Sralph * Fill the line with blanks to the specified column 35812113Sralph */ 35912113Sralph blankfill(n) 36012113Sralph register int n; 36112113Sralph { 36212113Sralph while (col++ < n) 36312113Sralph putchar(' '); 36412113Sralph } 36512113Sralph 36612113Sralph /* 36712113Sralph * Give the abbreviated dump of the file names 36812113Sralph */ 36912113Sralph dump(nfile, file, copies) 37012113Sralph char *nfile, *file; 37112113Sralph { 37212113Sralph register short n, fill; 37312113Sralph struct stat lbuf; 37412113Sralph 37512113Sralph /* 37612113Sralph * Print as many files as will fit 37712113Sralph * (leaving room for the total size) 37812113Sralph */ 37912113Sralph fill = first ? 0 : 2; /* fill space for ``, '' */ 38012113Sralph if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 38112113Sralph if (col < SIZCOL) { 38212113Sralph printf(" ..."), col += 4; 38312113Sralph blankfill(SIZCOL); 38412113Sralph } 38512113Sralph } else { 38612113Sralph if (first) 38712113Sralph first = 0; 38812113Sralph else 38912113Sralph printf(", "); 39012113Sralph printf("%s", nfile); 39112113Sralph col += n+fill; 39212113Sralph } 39312113Sralph if (*file && !stat(file, &lbuf)) 39412113Sralph totsize += copies * lbuf.st_size; 39512113Sralph } 39612113Sralph 39712113Sralph /* 39812113Sralph * Print the long info about the file 39912113Sralph */ 40012113Sralph ldump(nfile, file, copies) 40112113Sralph char *nfile, *file; 40212113Sralph { 40312113Sralph struct stat lbuf; 40412113Sralph 40512113Sralph putchar('\t'); 40612113Sralph if (copies > 1) 40712113Sralph printf("%-2d copies of %-19s", copies, nfile); 40812113Sralph else 40912113Sralph printf("%-32s", nfile); 41012113Sralph if (*file && !stat(file, &lbuf)) 411*34587Sbostic printf(" %ld bytes", lbuf.st_size); 41212113Sralph else 41312113Sralph printf(" ??? bytes"); 41412113Sralph putchar('\n'); 41512113Sralph } 41612113Sralph 41712113Sralph /* 41812113Sralph * Print the job's rank in the queue, 41912113Sralph * update col for screen management 42012113Sralph */ 42112113Sralph prank(n) 42212113Sralph { 42312113Sralph char line[100]; 42412113Sralph static char *r[] = { 42512113Sralph "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 42612113Sralph }; 42712113Sralph 42812113Sralph if (n == 0) { 42912113Sralph printf("active"); 43012113Sralph col += 6; 43112113Sralph return; 43212113Sralph } 43312113Sralph if ((n/10) == 1) 43412113Sralph (void) sprintf(line, "%dth", n); 43512113Sralph else 43612113Sralph (void) sprintf(line, "%d%s", n, r[n%10]); 43712113Sralph col += strlen(line); 43812113Sralph printf("%s", line); 43912113Sralph } 440