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