1*12113Sralph /* displayq.c 4.1 83/04/29 */ 2*12113Sralph /* 3*12113Sralph * Routines to display the state of the queue. 4*12113Sralph */ 5*12113Sralph 6*12113Sralph #include "lp.h" 7*12113Sralph 8*12113Sralph #define JOBCOL 40 /* column for job # in -l format */ 9*12113Sralph #define OWNCOL 7 /* start of Owner column in normal */ 10*12113Sralph 11*12113Sralph /* 12*12113Sralph * Stuff for handling job specifications 13*12113Sralph */ 14*12113Sralph extern char *user[]; /* users to process */ 15*12113Sralph extern int users; /* # of users in user array */ 16*12113Sralph extern int requ[]; /* job number of spool entries */ 17*12113Sralph extern int requests; /* # of spool requests */ 18*12113Sralph 19*12113Sralph int lflag; /* long output option */ 20*12113Sralph char current[40]; /* current file being printed */ 21*12113Sralph int garbage; /* # of garbage cf files */ 22*12113Sralph int rank; /* order to be printed (-1=none, 0=active) */ 23*12113Sralph long totsize; /* total print job size in bytes */ 24*12113Sralph int first; /* first file in ``files'' column? */ 25*12113Sralph int col; /* column on screen */ 26*12113Sralph int SIZCOL = 62; /* start of Size column in normal */ 27*12113Sralph int sendtorem; /* are we sending to a remote? */ 28*12113Sralph char file[132]; /* print file name */ 29*12113Sralph 30*12113Sralph char *head0 = "Rank Owner Job Files"; 31*12113Sralph char *head1 = "Total Size\n"; 32*12113Sralph 33*12113Sralph /* 34*12113Sralph * Display the current state of the queue. Format = 1 if long format. 35*12113Sralph */ 36*12113Sralph displayq(format) 37*12113Sralph int format; 38*12113Sralph { 39*12113Sralph register struct queue *q; 40*12113Sralph register int i, nitems, fd; 41*12113Sralph struct queue **queue; 42*12113Sralph struct stat statb; 43*12113Sralph FILE *fp; 44*12113Sralph 45*12113Sralph name = "displayq"; 46*12113Sralph lflag = format; 47*12113Sralph totsize = 0; 48*12113Sralph rank = -1; 49*12113Sralph 50*12113Sralph if ((i = pgetent(line, printer)) < 0) 51*12113Sralph fatal("cannot open printer description file"); 52*12113Sralph else if (i == 0) 53*12113Sralph fatal("unknown printer"); 54*12113Sralph if ((LP = pgetstr("lp", &bp)) == NULL) 55*12113Sralph LP = DEFDEVLP; 56*12113Sralph if ((RP = pgetstr("rp", &bp)) == NULL) 57*12113Sralph RP = printer; 58*12113Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 59*12113Sralph SD = DEFSPOOL; 60*12113Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 61*12113Sralph LO = DEFLOCK; 62*12113Sralph if ((ST = pgetstr("st", &bp)) == NULL) 63*12113Sralph ST = DEFSTAT; 64*12113Sralph RM = pgetstr("rm", &bp); 65*12113Sralph 66*12113Sralph /* 67*12113Sralph * If there is no local printer, then print the queue on 68*12113Sralph * the remote machine and then what's in the queue here. 69*12113Sralph * Note that a file in transit may not show up in either queue. 70*12113Sralph */ 71*12113Sralph if (*LP == '\0') { 72*12113Sralph register char *cp; 73*12113Sralph char c; 74*12113Sralph 75*12113Sralph sendtorem++; 76*12113Sralph (void) sprintf(line, "%c%s", format + '\3', RP); 77*12113Sralph cp = line; 78*12113Sralph for (i = 0; i < requests; i++) { 79*12113Sralph cp += strlen(cp); 80*12113Sralph (void) sprintf(cp, " %d", requ[i]); 81*12113Sralph } 82*12113Sralph for (i = 0; i < users; i++) { 83*12113Sralph cp += strlen(cp); 84*12113Sralph *cp++ = ' '; 85*12113Sralph strcpy(cp, user[i]); 86*12113Sralph } 87*12113Sralph strcat(line, "\n"); 88*12113Sralph fd = getport(); 89*12113Sralph if (fd < 0) { 90*12113Sralph if (from != host) 91*12113Sralph printf("%s: ", host); 92*12113Sralph printf("connection to %s is down\n", RM); 93*12113Sralph } else { 94*12113Sralph i = strlen(line); 95*12113Sralph if (write(fd, line, i) != i) 96*12113Sralph fatal("Lost connection"); 97*12113Sralph while ((i = read(fd, line, sizeof(line))) > 0) 98*12113Sralph (void) fwrite(line, 1, i, stdout); 99*12113Sralph (void) close(fd); 100*12113Sralph } 101*12113Sralph } 102*12113Sralph /* 103*12113Sralph * Find all the control files in the spooling directory 104*12113Sralph */ 105*12113Sralph if (chdir(SD) < 0) 106*12113Sralph fatal("cannot chdir to spooling directory"); 107*12113Sralph if ((nitems = getq(&queue)) < 0) 108*12113Sralph fatal("cannot examine spooling area\n"); 109*12113Sralph if (nitems == 0) { 110*12113Sralph if (sendtorem) 111*12113Sralph printf("\n%s: ", host); 112*12113Sralph printf("no entries\n"); 113*12113Sralph return(0); 114*12113Sralph } 115*12113Sralph fp = fopen(LO, "r"); 116*12113Sralph if (fp == NULL || flock(fileno(fp), FSHLOCK|FNBLOCK) == 0) { 117*12113Sralph if (fp != NULL) 118*12113Sralph fclose(fp); 119*12113Sralph garbage = nitems; 120*12113Sralph if (*LP && stat(LP, &statb) >= 0 && (statb.st_mode & 0777) == 0) 121*12113Sralph status("Warning: %s is down", printer); 122*12113Sralph else 123*12113Sralph status("Warning: no daemon present"); 124*12113Sralph } else { 125*12113Sralph register char *cp = current; 126*12113Sralph 127*12113Sralph /* skip daemon pid */ 128*12113Sralph while ((*cp = getc(fp)) != EOF && *cp != '\n'); 129*12113Sralph /* read current file name */ 130*12113Sralph while ((*cp = getc(fp)) != EOF && *cp != '\n') 131*12113Sralph cp++; 132*12113Sralph *cp = '\0'; 133*12113Sralph fclose(fp); 134*12113Sralph } 135*12113Sralph /* 136*12113Sralph * Now, examine the control files and print out the jobs to 137*12113Sralph * be done for each user. 138*12113Sralph */ 139*12113Sralph if (sendtorem) 140*12113Sralph printf("\n%s: ", host); 141*12113Sralph if ((fd = open(ST, FRDONLY|FSHLOCK)) >= 0) { 142*12113Sralph while ((i = read(fd, line, sizeof(line))) > 0) 143*12113Sralph (void) fwrite(line, 1, i, stdout); 144*12113Sralph (void) close(fd); 145*12113Sralph } else 146*12113Sralph putchar('\n'); 147*12113Sralph if (!lflag) 148*12113Sralph header(); 149*12113Sralph for (i = 0; i < nitems; i++) { 150*12113Sralph q = queue[i]; 151*12113Sralph inform(q->q_name); 152*12113Sralph free(q); 153*12113Sralph } 154*12113Sralph free(queue); 155*12113Sralph return(nitems-garbage); 156*12113Sralph } 157*12113Sralph 158*12113Sralph /* 159*12113Sralph * Print the header for the short listing format 160*12113Sralph */ 161*12113Sralph header() 162*12113Sralph { 163*12113Sralph printf(head0); 164*12113Sralph col = strlen(head0)+1; 165*12113Sralph blankfill(SIZCOL); 166*12113Sralph printf(head1); 167*12113Sralph } 168*12113Sralph 169*12113Sralph inform(cf) 170*12113Sralph char *cf; 171*12113Sralph { 172*12113Sralph register int j, k; 173*12113Sralph register char *cp; 174*12113Sralph FILE *cfp; 175*12113Sralph 176*12113Sralph /* 177*12113Sralph * There's a chance the control file has gone away 178*12113Sralph * in the meantime; if this is the case just keep going 179*12113Sralph */ 180*12113Sralph if ((cfp = fopen(cf, "r")) == NULL) 181*12113Sralph return; 182*12113Sralph 183*12113Sralph if (rank < 0) 184*12113Sralph rank = 0; 185*12113Sralph if (sendtorem || garbage || strcmp(cf, current)) 186*12113Sralph rank++; 187*12113Sralph j = 0; 188*12113Sralph while (getline(cfp)) { 189*12113Sralph switch (line[0]) { 190*12113Sralph case 'P': /* Was this file specified in the user's list? */ 191*12113Sralph if (!inlist(line+1, cf)) { 192*12113Sralph fclose(cfp); 193*12113Sralph return; 194*12113Sralph } 195*12113Sralph if (lflag) { 196*12113Sralph printf("\n%s: ", line+1); 197*12113Sralph col = strlen(line+1) + 2; 198*12113Sralph prank(rank); 199*12113Sralph blankfill(JOBCOL); 200*12113Sralph printf(" [job %s]\n", cf+3); 201*12113Sralph } else { 202*12113Sralph col = 0; 203*12113Sralph prank(rank); 204*12113Sralph blankfill(OWNCOL); 205*12113Sralph printf("%-10s %-3d ", line+1, atoi(cf+3)); 206*12113Sralph col += 16; 207*12113Sralph first = 1; 208*12113Sralph } 209*12113Sralph continue; 210*12113Sralph default: /* some format specifer and file name? */ 211*12113Sralph if (line[0] < 'a' || line[0] > 'z') 212*12113Sralph continue; 213*12113Sralph if (j == 0 || strcmp(file, line+1) != 0) 214*12113Sralph strcpy(file, line+1); 215*12113Sralph j++; 216*12113Sralph continue; 217*12113Sralph case 'N': 218*12113Sralph show(line+1, file, j); 219*12113Sralph file[0] = '\0'; 220*12113Sralph j = 0; 221*12113Sralph } 222*12113Sralph } 223*12113Sralph fclose(cfp); 224*12113Sralph if (!lflag) { 225*12113Sralph blankfill(SIZCOL); 226*12113Sralph printf("%D bytes\n", totsize); 227*12113Sralph totsize = 0; 228*12113Sralph } 229*12113Sralph } 230*12113Sralph 231*12113Sralph inlist(name, file) 232*12113Sralph char *name, *file; 233*12113Sralph { 234*12113Sralph register int *r, n; 235*12113Sralph register char **u, *cp; 236*12113Sralph 237*12113Sralph if (users == 0 && requests == 0) 238*12113Sralph return(1); 239*12113Sralph /* 240*12113Sralph * Check to see if it's in the user list 241*12113Sralph */ 242*12113Sralph for (u = user; u < &user[users]; u++) 243*12113Sralph if (!strcmp(*u, name)) 244*12113Sralph return(1); 245*12113Sralph /* 246*12113Sralph * Check the request list 247*12113Sralph */ 248*12113Sralph for (n = 0, cp = file+3; isdigit(*cp); ) 249*12113Sralph n = n * 10 + (*cp++ - '0'); 250*12113Sralph for (r = requ; r < &requ[requests]; r++) 251*12113Sralph if (*r == n && !strcmp(cp, from)) 252*12113Sralph return(1); 253*12113Sralph return(0); 254*12113Sralph } 255*12113Sralph 256*12113Sralph show(nfile, file, copies) 257*12113Sralph register char *nfile, *file; 258*12113Sralph { 259*12113Sralph if (strcmp(nfile, " ") == 0) 260*12113Sralph nfile = "(standard input)"; 261*12113Sralph if (lflag) 262*12113Sralph ldump(nfile, file, copies); 263*12113Sralph else 264*12113Sralph dump(nfile, file, copies); 265*12113Sralph } 266*12113Sralph 267*12113Sralph /* 268*12113Sralph * Fill the line with blanks to the specified column 269*12113Sralph */ 270*12113Sralph blankfill(n) 271*12113Sralph register int n; 272*12113Sralph { 273*12113Sralph while (col++ < n) 274*12113Sralph putchar(' '); 275*12113Sralph } 276*12113Sralph 277*12113Sralph /* 278*12113Sralph * Give the abbreviated dump of the file names 279*12113Sralph */ 280*12113Sralph dump(nfile, file, copies) 281*12113Sralph char *nfile, *file; 282*12113Sralph { 283*12113Sralph register short n, fill; 284*12113Sralph struct stat lbuf; 285*12113Sralph 286*12113Sralph /* 287*12113Sralph * Print as many files as will fit 288*12113Sralph * (leaving room for the total size) 289*12113Sralph */ 290*12113Sralph fill = first ? 0 : 2; /* fill space for ``, '' */ 291*12113Sralph if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { 292*12113Sralph if (col < SIZCOL) { 293*12113Sralph printf(" ..."), col += 4; 294*12113Sralph blankfill(SIZCOL); 295*12113Sralph } 296*12113Sralph } else { 297*12113Sralph if (first) 298*12113Sralph first = 0; 299*12113Sralph else 300*12113Sralph printf(", "); 301*12113Sralph printf("%s", nfile); 302*12113Sralph col += n+fill; 303*12113Sralph } 304*12113Sralph if (*file && !stat(file, &lbuf)) 305*12113Sralph totsize += copies * lbuf.st_size; 306*12113Sralph } 307*12113Sralph 308*12113Sralph /* 309*12113Sralph * Print the long info about the file 310*12113Sralph */ 311*12113Sralph ldump(nfile, file, copies) 312*12113Sralph char *nfile, *file; 313*12113Sralph { 314*12113Sralph struct stat lbuf; 315*12113Sralph 316*12113Sralph putchar('\t'); 317*12113Sralph if (copies > 1) 318*12113Sralph printf("%-2d copies of %-19s", copies, nfile); 319*12113Sralph else 320*12113Sralph printf("%-32s", nfile); 321*12113Sralph if (*file && !stat(file, &lbuf)) 322*12113Sralph printf(" %D bytes", lbuf.st_size); 323*12113Sralph else 324*12113Sralph printf(" ??? bytes"); 325*12113Sralph putchar('\n'); 326*12113Sralph } 327*12113Sralph 328*12113Sralph /* 329*12113Sralph * Print the job's rank in the queue, 330*12113Sralph * update col for screen management 331*12113Sralph */ 332*12113Sralph prank(n) 333*12113Sralph { 334*12113Sralph char line[100]; 335*12113Sralph static char *r[] = { 336*12113Sralph "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 337*12113Sralph }; 338*12113Sralph 339*12113Sralph if (n == 0) { 340*12113Sralph printf("active"); 341*12113Sralph col += 6; 342*12113Sralph return; 343*12113Sralph } 344*12113Sralph if ((n/10) == 1) 345*12113Sralph (void) sprintf(line, "%dth", n); 346*12113Sralph else 347*12113Sralph (void) sprintf(line, "%d%s", n, r[n%10]); 348*12113Sralph col += strlen(line); 349*12113Sralph printf("%s", line); 350*12113Sralph } 351