122427Sdist /* 222427Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 5*42801Sbostic * %sccs.include.redist.c% 622427Sdist */ 722427Sdist 813952Ssam #ifndef lint 9*42801Sbostic static char sccsid[] = "@(#)displayq.c 5.13 (Berkeley) 06/01/90"; 1034203Sbostic #endif /* not lint */ 1113952Ssam 1212113Sralph /* 1312113Sralph * Routines to display the state of the queue. 1412113Sralph */ 1512113Sralph 1612113Sralph #include "lp.h" 1737968Sbostic #include "pathnames.h" 1812113Sralph 1913170Sralph #define JOBCOL 40 /* column for job # in -l format */ 2013170Sralph #define OWNCOL 7 /* start of Owner column in normal */ 2113170Sralph #define SIZCOL 62 /* start of Size column in normal */ 2212113Sralph 2312113Sralph /* 2412113Sralph * Stuff for handling job specifications 2512113Sralph */ 2612113Sralph extern char *user[]; /* users to process */ 2712113Sralph extern int users; /* # of users in user array */ 2812113Sralph extern int requ[]; /* job number of spool entries */ 2912113Sralph extern int requests; /* # of spool requests */ 3012113Sralph 3116758Sralph int lflag; /* long output option */ 3216758Sralph char current[40]; /* current file being printed */ 3316758Sralph int garbage; /* # of garbage cf files */ 3416758Sralph int rank; /* order to be printed (-1=none, 0=active) */ 3516758Sralph long totsize; /* total print job size in bytes */ 3616758Sralph int first; /* first file in ``files'' column? */ 3716758Sralph int col; /* column on screen */ 3816758Sralph char file[132]; /* print file name */ 3912113Sralph 4016758Sralph char *head0 = "Rank Owner Job Files"; 4116758Sralph char *head1 = "Total Size\n"; 4212113Sralph 4312113Sralph /* 4412113Sralph * Display the current state of the queue. Format = 1 if long format. 4512113Sralph */ 4612113Sralph displayq(format) 4712113Sralph int format; 4812113Sralph { 4912113Sralph register struct queue *q; 5012113Sralph register int i, nitems, fd; 5130995Sbostic register char *cp; 5212113Sralph struct queue **queue; 5312113Sralph struct stat statb; 5412113Sralph FILE *fp; 5530995Sbostic char c; 5612113Sralph 5712113Sralph lflag = format; 5812113Sralph totsize = 0; 5912113Sralph rank = -1; 6012113Sralph 6112113Sralph if ((i = pgetent(line, printer)) < 0) 6212113Sralph fatal("cannot open printer description file"); 6312113Sralph else if (i == 0) 6412113Sralph fatal("unknown printer"); 6512113Sralph if ((LP = pgetstr("lp", &bp)) == NULL) 6637968Sbostic LP = _PATH_DEFDEVLP; 6712113Sralph if ((RP = pgetstr("rp", &bp)) == NULL) 6812434Sralph RP = DEFLP; 6912113Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 7037968Sbostic SD = _PATH_DEFSPOOL; 7112113Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 7212113Sralph LO = DEFLOCK; 7312113Sralph if ((ST = pgetstr("st", &bp)) == NULL) 7412113Sralph ST = DEFSTAT; 7512113Sralph RM = pgetstr("rm", &bp); 7638736Stef if (cp = checkremote()) 7738736Stef printf("Warning: %s\n", cp); 7812113Sralph 7912113Sralph /* 8030995Sbostic * Print out local queue 8112113Sralph * Find all the control files in the spooling directory 8212113Sralph */ 8312113Sralph if (chdir(SD) < 0) 8412113Sralph fatal("cannot chdir to spooling directory"); 8512113Sralph if ((nitems = getq(&queue)) < 0) 8612113Sralph fatal("cannot examine spooling area\n"); 8716205Sralph if (stat(LO, &statb) >= 0) { 8816205Sralph if (statb.st_mode & 0100) { 8916205Sralph if (sendtorem) 9016205Sralph printf("%s: ", host); 9116205Sralph printf("Warning: %s is down: ", printer); 9216205Sralph fd = open(ST, O_RDONLY); 9316205Sralph if (fd >= 0) { 9416205Sralph (void) flock(fd, LOCK_SH); 9516205Sralph while ((i = read(fd, line, sizeof(line))) > 0) 9616205Sralph (void) fwrite(line, 1, i, stdout); 9716205Sralph (void) close(fd); /* unlocks as well */ 9816205Sralph } else 9916205Sralph putchar('\n'); 10016205Sralph } 10116205Sralph if (statb.st_mode & 010) { 10216205Sralph if (sendtorem) 10316205Sralph printf("%s: ", host); 10416205Sralph printf("Warning: %s queue is turned off\n", printer); 10516205Sralph } 10612740Sralph } 10712113Sralph 10830995Sbostic if (nitems) { 10930995Sbostic fp = fopen(LO, "r"); 11030995Sbostic if (fp == NULL) 11113441Sralph warn(); 11213441Sralph else { 11330995Sbostic /* get daemon pid */ 11413441Sralph cp = current; 11513441Sralph while ((*cp = getc(fp)) != EOF && *cp != '\n') 11613441Sralph cp++; 11713441Sralph *cp = '\0'; 11830995Sbostic i = atoi(current); 11930995Sbostic if (i <= 0 || kill(i, 0) < 0) 12030995Sbostic warn(); 12130995Sbostic else { 12230995Sbostic /* read current file name */ 12330995Sbostic cp = current; 12430995Sbostic while ((*cp = getc(fp)) != EOF && *cp != '\n') 12530995Sbostic cp++; 12630995Sbostic *cp = '\0'; 12730995Sbostic /* 12830995Sbostic * Print the status file. 12930995Sbostic */ 13030995Sbostic if (sendtorem) 13130995Sbostic printf("%s: ", host); 13230995Sbostic fd = open(ST, O_RDONLY); 13330995Sbostic if (fd >= 0) { 13430995Sbostic (void) flock(fd, LOCK_SH); 13530995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 13630995Sbostic (void) fwrite(line, 1, i, stdout); 13730995Sbostic (void) close(fd); /* unlocks as well */ 13830995Sbostic } else 13930995Sbostic putchar('\n'); 14030995Sbostic } 14130995Sbostic (void) fclose(fp); 14213441Sralph } 14330995Sbostic /* 14430995Sbostic * Now, examine the control files and print out the jobs to 14530995Sbostic * be done for each user. 14630995Sbostic */ 14730995Sbostic if (!lflag) 14830995Sbostic header(); 14930995Sbostic for (i = 0; i < nitems; i++) { 15030995Sbostic q = queue[i]; 15130995Sbostic inform(q->q_name); 15230995Sbostic free(q); 15330995Sbostic } 15430995Sbostic free(queue); 15512113Sralph } 15631678Skarels if (!sendtorem) { 15731678Skarels if (nitems == 0) 15831678Skarels puts("no entries"); 15930995Sbostic return; 16030995Sbostic } 16130995Sbostic 16212113Sralph /* 16330995Sbostic * Print foreign queue 16430995Sbostic * Note that a file in transit may show up in either queue. 16512113Sralph */ 16630995Sbostic if (nitems) 16730995Sbostic putchar('\n'); 16830995Sbostic (void) sprintf(line, "%c%s", format + '\3', RP); 16930995Sbostic cp = line; 17030995Sbostic for (i = 0; i < requests; i++) { 17130995Sbostic cp += strlen(cp); 17230995Sbostic (void) sprintf(cp, " %d", requ[i]); 17312113Sralph } 17430995Sbostic for (i = 0; i < users; i++) { 17530995Sbostic cp += strlen(cp); 17630995Sbostic *cp++ = ' '; 17730995Sbostic (void) strcpy(cp, user[i]); 17830995Sbostic } 17930995Sbostic strcat(line, "\n"); 18030995Sbostic fd = getport(RM); 18130995Sbostic if (fd < 0) { 18230995Sbostic if (from != host) 18330995Sbostic printf("%s: ", host); 18430995Sbostic printf("connection to %s is down\n", RM); 18530995Sbostic } 18630995Sbostic else { 18730995Sbostic i = strlen(line); 18830995Sbostic if (write(fd, line, i) != i) 18930995Sbostic fatal("Lost connection"); 19030995Sbostic while ((i = read(fd, line, sizeof(line))) > 0) 19130995Sbostic (void) fwrite(line, 1, i, stdout); 19230995Sbostic (void) close(fd); 19330995Sbostic } 19412113Sralph } 19512113Sralph 19612113Sralph /* 19713441Sralph * Print a warning message if there is no daemon present. 19813441Sralph */ 19913441Sralph warn() 20013441Sralph { 20113441Sralph if (sendtorem) 20213441Sralph printf("\n%s: ", host); 20330995Sbostic puts("Warning: no daemon present"); 20413441Sralph current[0] = '\0'; 20513441Sralph } 20613441Sralph 20713441Sralph /* 20812113Sralph * Print the header for the short listing format 20912113Sralph */ 21012113Sralph header() 21112113Sralph { 21212113Sralph printf(head0); 21312113Sralph col = strlen(head0)+1; 21412113Sralph blankfill(SIZCOL); 21512113Sralph printf(head1); 21612113Sralph } 21712113Sralph 21812113Sralph inform(cf) 21912113Sralph char *cf; 22012113Sralph { 22112113Sralph register int j, k; 22212113Sralph register char *cp; 22312113Sralph FILE *cfp; 22412113Sralph 22512113Sralph /* 22612113Sralph * There's a chance the control file has gone away 22712113Sralph * in the meantime; if this is the case just keep going 22812113Sralph */ 22912113Sralph if ((cfp = fopen(cf, "r")) == NULL) 23012113Sralph return; 23112113Sralph 23212113Sralph if (rank < 0) 23312113Sralph rank = 0; 23412113Sralph if (sendtorem || garbage || strcmp(cf, current)) 23512113Sralph rank++; 23612113Sralph j = 0; 23712113Sralph while (getline(cfp)) { 23812113Sralph switch (line[0]) { 23912113Sralph case 'P': /* Was this file specified in the user's list? */ 24012113Sralph if (!inlist(line+1, cf)) { 24112113Sralph fclose(cfp); 24212113Sralph return; 24312113Sralph } 24412113Sralph if (lflag) { 24512113Sralph printf("\n%s: ", line+1); 24612113Sralph col = strlen(line+1) + 2; 24712113Sralph prank(rank); 24812113Sralph blankfill(JOBCOL); 24912113Sralph printf(" [job %s]\n", cf+3); 25012113Sralph } else { 25112113Sralph col = 0; 25212113Sralph prank(rank); 25312113Sralph blankfill(OWNCOL); 25412113Sralph printf("%-10s %-3d ", line+1, atoi(cf+3)); 25512113Sralph col += 16; 25612113Sralph first = 1; 25712113Sralph } 25812113Sralph continue; 25912113Sralph default: /* some format specifer and file name? */ 26012113Sralph if (line[0] < 'a' || line[0] > 'z') 26112113Sralph continue; 26212113Sralph if (j == 0 || strcmp(file, line+1) != 0) 26330995Sbostic (void) strcpy(file, line+1); 26412113Sralph j++; 26512113Sralph continue; 26612113Sralph case 'N': 26712113Sralph show(line+1, file, j); 26812113Sralph file[0] = '\0'; 26912113Sralph j = 0; 27012113Sralph } 27112113Sralph } 27212113Sralph fclose(cfp); 27312113Sralph if (!lflag) { 27412113Sralph blankfill(SIZCOL); 27534587Sbostic printf("%ld bytes\n", totsize); 27612113Sralph totsize = 0; 27712113Sralph } 27812113Sralph } 27912113Sralph 28012113Sralph inlist(name, file) 28112113Sralph char *name, *file; 28212113Sralph { 28312113Sralph register int *r, n; 28412113Sralph register char **u, *cp; 28512113Sralph 28612113Sralph if (users == 0 && requests == 0) 28712113Sralph return(1); 28812113Sralph /* 28912113Sralph * Check to see if it's in the user list 29012113Sralph */ 29112113Sralph for (u = user; u < &user[users]; u++) 29212113Sralph if (!strcmp(*u, name)) 29312113Sralph return(1); 29412113Sralph /* 29512113Sralph * Check the request list 29612113Sralph */ 29712113Sralph for (n = 0, cp = file+3; isdigit(*cp); ) 29812113Sralph n = n * 10 + (*cp++ - '0'); 29912113Sralph for (r = requ; r < &requ[requests]; r++) 30012113Sralph if (*r == n && !strcmp(cp, from)) 30112113Sralph return(1); 30212113Sralph return(0); 30312113Sralph } 30412113Sralph 30512113Sralph show(nfile, file, copies) 30612113Sralph register char *nfile, *file; 30712113Sralph { 30812113Sralph if (strcmp(nfile, " ") == 0) 30912113Sralph nfile = "(standard input)"; 31012113Sralph if (lflag) 31112113Sralph ldump(nfile, file, copies); 31212113Sralph else 31312113Sralph dump(nfile, file, copies); 31412113Sralph } 31512113Sralph 31612113Sralph /* 31712113Sralph * Fill the line with blanks to the specified column 31812113Sralph */ 31912113Sralph blankfill(n) 32012113Sralph register int n; 32112113Sralph { 32212113Sralph while (col++ < n) 32312113Sralph putchar(' '); 32412113Sralph } 32512113Sralph 32612113Sralph /* 32712113Sralph * Give the abbreviated dump of the file names 32812113Sralph */ 32912113Sralph dump(nfile, file, copies) 33012113Sralph char *nfile, *file; 33112113Sralph { 33212113Sralph register short n, fill; 33312113Sralph struct stat lbuf; 33412113Sralph 33512113Sralph /* 33612113Sralph * Print as many files as will fit 33712113Sralph * (leaving room for the total size) 33812113Sralph */ 33912113Sralph fill = first ? 0 : 2; /* fill space for ``, '' */ 34012113Sralph if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 34112113Sralph if (col < SIZCOL) { 34212113Sralph printf(" ..."), col += 4; 34312113Sralph blankfill(SIZCOL); 34412113Sralph } 34512113Sralph } else { 34612113Sralph if (first) 34712113Sralph first = 0; 34812113Sralph else 34912113Sralph printf(", "); 35012113Sralph printf("%s", nfile); 35112113Sralph col += n+fill; 35212113Sralph } 35312113Sralph if (*file && !stat(file, &lbuf)) 35412113Sralph totsize += copies * lbuf.st_size; 35512113Sralph } 35612113Sralph 35712113Sralph /* 35812113Sralph * Print the long info about the file 35912113Sralph */ 36012113Sralph ldump(nfile, file, copies) 36112113Sralph char *nfile, *file; 36212113Sralph { 36312113Sralph struct stat lbuf; 36412113Sralph 36512113Sralph putchar('\t'); 36612113Sralph if (copies > 1) 36712113Sralph printf("%-2d copies of %-19s", copies, nfile); 36812113Sralph else 36912113Sralph printf("%-32s", nfile); 37012113Sralph if (*file && !stat(file, &lbuf)) 37134587Sbostic printf(" %ld bytes", lbuf.st_size); 37212113Sralph else 37312113Sralph printf(" ??? bytes"); 37412113Sralph putchar('\n'); 37512113Sralph } 37612113Sralph 37712113Sralph /* 37812113Sralph * Print the job's rank in the queue, 37912113Sralph * update col for screen management 38012113Sralph */ 38112113Sralph prank(n) 38212113Sralph { 38312113Sralph char line[100]; 38412113Sralph static char *r[] = { 38512113Sralph "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 38612113Sralph }; 38712113Sralph 38812113Sralph if (n == 0) { 38912113Sralph printf("active"); 39012113Sralph col += 6; 39112113Sralph return; 39212113Sralph } 39338491Sbostic if ((n/10)%10 == 1) 39412113Sralph (void) sprintf(line, "%dth", n); 39512113Sralph else 39612113Sralph (void) sprintf(line, "%d%s", n, r[n%10]); 39712113Sralph col += strlen(line); 39812113Sralph printf("%s", line); 39912113Sralph } 400