|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)cmds.c 5.2 (Berkeley) 3/30/86"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * lpc -- line printer control program -- commands: ! 13: */ ! 14: ! 15: #include "lp.h" ! 16: #include <sys/time.h> ! 17: ! 18: /* ! 19: * kill an existing daemon and disable printing. ! 20: */ ! 21: abort(argc, argv) ! 22: char *argv[]; ! 23: { ! 24: register int c, status; ! 25: register char *cp1, *cp2; ! 26: char prbuf[100]; ! 27: ! 28: if (argc == 1) { ! 29: printf("Usage: abort {all | printer ...}\n"); ! 30: return; ! 31: } ! 32: if (argc == 2 && !strcmp(argv[1], "all")) { ! 33: printer = prbuf; ! 34: while (getprent(line) > 0) { ! 35: cp1 = prbuf; ! 36: cp2 = line; ! 37: while ((c = *cp2++) && c != '|' && c != ':') ! 38: *cp1++ = c; ! 39: *cp1 = '\0'; ! 40: abortpr(1); ! 41: } ! 42: return; ! 43: } ! 44: while (--argc) { ! 45: printer = *++argv; ! 46: if ((status = pgetent(line, printer)) < 0) { ! 47: printf("cannot open printer description file\n"); ! 48: continue; ! 49: } else if (status == 0) { ! 50: printf("unknown printer %s\n", printer); ! 51: continue; ! 52: } ! 53: abortpr(1); ! 54: } ! 55: } ! 56: ! 57: abortpr(dis) ! 58: { ! 59: register FILE *fp; ! 60: struct stat stbuf; ! 61: int pid, fd; ! 62: ! 63: bp = pbuf; ! 64: if ((SD = pgetstr("sd", &bp)) == NULL) ! 65: SD = DEFSPOOL; ! 66: if ((LO = pgetstr("lo", &bp)) == NULL) ! 67: LO = DEFLOCK; ! 68: (void) sprintf(line, "%s/%s", SD, LO); ! 69: printf("%s:\n", printer); ! 70: ! 71: /* ! 72: * Turn on the owner execute bit of the lock file to disable printing. ! 73: */ ! 74: if (dis) { ! 75: if (stat(line, &stbuf) >= 0) { ! 76: if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) ! 77: printf("\tcannot disable printing\n"); ! 78: else ! 79: printf("\tprinting disabled\n"); ! 80: } else if (errno == ENOENT) { ! 81: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) ! 82: printf("\tcannot create lock file\n"); ! 83: else { ! 84: (void) close(fd); ! 85: printf("\tprinting disabled\n"); ! 86: printf("\tno daemon to abort\n"); ! 87: } ! 88: return; ! 89: } else { ! 90: printf("\tcannot stat lock file\n"); ! 91: return; ! 92: } ! 93: } ! 94: /* ! 95: * Kill the current daemon to stop printing now. ! 96: */ ! 97: if ((fp = fopen(line, "r")) == NULL) { ! 98: printf("\tcannot open lock file\n"); ! 99: return; ! 100: } ! 101: if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { ! 102: (void) fclose(fp); /* unlocks as well */ ! 103: printf("\tno daemon to abort\n"); ! 104: return; ! 105: } ! 106: (void) fclose(fp); ! 107: if (kill(pid = atoi(line), SIGTERM) < 0) ! 108: printf("\tWarning: daemon (pid %d) not killed\n", pid); ! 109: else ! 110: printf("\tdaemon (pid %d) killed\n", pid); ! 111: } ! 112: ! 113: /* ! 114: * Remove all spool files and temporaries from the spooling area. ! 115: */ ! 116: clean(argc, argv) ! 117: char *argv[]; ! 118: { ! 119: register int c, status; ! 120: register char *cp1, *cp2; ! 121: char prbuf[100]; ! 122: ! 123: if (argc == 1) { ! 124: printf("Usage: clean {all | printer ...}\n"); ! 125: return; ! 126: } ! 127: if (argc == 2 && !strcmp(argv[1], "all")) { ! 128: printer = prbuf; ! 129: while (getprent(line) > 0) { ! 130: cp1 = prbuf; ! 131: cp2 = line; ! 132: while ((c = *cp2++) && c != '|' && c != ':') ! 133: *cp1++ = c; ! 134: *cp1 = '\0'; ! 135: cleanpr(); ! 136: } ! 137: return; ! 138: } ! 139: while (--argc) { ! 140: printer = *++argv; ! 141: if ((status = pgetent(line, printer)) < 0) { ! 142: printf("cannot open printer description file\n"); ! 143: continue; ! 144: } else if (status == 0) { ! 145: printf("unknown printer %s\n", printer); ! 146: continue; ! 147: } ! 148: cleanpr(); ! 149: } ! 150: } ! 151: ! 152: select(d) ! 153: struct direct *d; ! 154: { ! 155: int c = d->d_name[0]; ! 156: ! 157: if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') ! 158: return(1); ! 159: return(0); ! 160: } ! 161: ! 162: /* ! 163: * Comparison routine for scandir. Sort by job number and machine, then ! 164: * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. ! 165: */ ! 166: sortq(d1, d2) ! 167: struct direct **d1, **d2; ! 168: { ! 169: int c1, c2; ! 170: ! 171: if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) ! 172: return(c1); ! 173: c1 = (*d1)->d_name[0]; ! 174: c2 = (*d2)->d_name[0]; ! 175: if (c1 == c2) ! 176: return((*d1)->d_name[2] - (*d2)->d_name[2]); ! 177: if (c1 == 'c') ! 178: return(-1); ! 179: if (c1 == 'd' || c2 == 'c') ! 180: return(1); ! 181: return(-1); ! 182: } ! 183: ! 184: /* ! 185: * Remove incomplete jobs from spooling area. ! 186: */ ! 187: cleanpr() ! 188: { ! 189: register int i, n; ! 190: register char *cp, *cp1, *lp; ! 191: struct direct **queue; ! 192: int nitems; ! 193: ! 194: bp = pbuf; ! 195: if ((SD = pgetstr("sd", &bp)) == NULL) ! 196: SD = DEFSPOOL; ! 197: printf("%s:\n", printer); ! 198: ! 199: for (lp = line, cp = SD; *lp++ = *cp++; ) ! 200: ; ! 201: lp[-1] = '/'; ! 202: ! 203: nitems = scandir(SD, &queue, select, sortq); ! 204: if (nitems < 0) { ! 205: printf("\tcannot examine spool directory\n"); ! 206: return; ! 207: } ! 208: if (nitems == 0) ! 209: return; ! 210: i = 0; ! 211: do { ! 212: cp = queue[i]->d_name; ! 213: if (*cp == 'c') { ! 214: n = 0; ! 215: while (i + 1 < nitems) { ! 216: cp1 = queue[i + 1]->d_name; ! 217: if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) ! 218: break; ! 219: i++; ! 220: n++; ! 221: } ! 222: if (n == 0) { ! 223: strcpy(lp, cp); ! 224: unlinkf(line); ! 225: } ! 226: } else { ! 227: /* ! 228: * Must be a df with no cf (otherwise, it would have ! 229: * been skipped above) or a tf file (which can always ! 230: * be removed). ! 231: */ ! 232: strcpy(lp, cp); ! 233: unlinkf(line); ! 234: } ! 235: } while (++i < nitems); ! 236: } ! 237: ! 238: unlinkf(name) ! 239: char *name; ! 240: { ! 241: if (unlink(name) < 0) ! 242: printf("\tcannot remove %s\n", name); ! 243: else ! 244: printf("\tremoved %s\n", name); ! 245: } ! 246: ! 247: /* ! 248: * Enable queuing to the printer (allow lpr's). ! 249: */ ! 250: enable(argc, argv) ! 251: char *argv[]; ! 252: { ! 253: register int c, status; ! 254: register char *cp1, *cp2; ! 255: char prbuf[100]; ! 256: ! 257: if (argc == 1) { ! 258: printf("Usage: enable {all | printer ...}\n"); ! 259: return; ! 260: } ! 261: if (argc == 2 && !strcmp(argv[1], "all")) { ! 262: printer = prbuf; ! 263: while (getprent(line) > 0) { ! 264: cp1 = prbuf; ! 265: cp2 = line; ! 266: while ((c = *cp2++) && c != '|' && c != ':') ! 267: *cp1++ = c; ! 268: *cp1 = '\0'; ! 269: enablepr(); ! 270: } ! 271: return; ! 272: } ! 273: while (--argc) { ! 274: printer = *++argv; ! 275: if ((status = pgetent(line, printer)) < 0) { ! 276: printf("cannot open printer description file\n"); ! 277: continue; ! 278: } else if (status == 0) { ! 279: printf("unknown printer %s\n", printer); ! 280: continue; ! 281: } ! 282: enablepr(); ! 283: } ! 284: } ! 285: ! 286: enablepr() ! 287: { ! 288: struct stat stbuf; ! 289: ! 290: bp = pbuf; ! 291: if ((SD = pgetstr("sd", &bp)) == NULL) ! 292: SD = DEFSPOOL; ! 293: if ((LO = pgetstr("lo", &bp)) == NULL) ! 294: LO = DEFLOCK; ! 295: (void) sprintf(line, "%s/%s", SD, LO); ! 296: printf("%s:\n", printer); ! 297: ! 298: /* ! 299: * Turn off the group execute bit of the lock file to enable queuing. ! 300: */ ! 301: if (stat(line, &stbuf) >= 0) { ! 302: if (chmod(line, stbuf.st_mode & 0767) < 0) ! 303: printf("\tcannot enable queuing\n"); ! 304: else ! 305: printf("\tqueuing enabled\n"); ! 306: } ! 307: } ! 308: ! 309: /* ! 310: * Disable queuing. ! 311: */ ! 312: disable(argc, argv) ! 313: char *argv[]; ! 314: { ! 315: register int c, status; ! 316: register char *cp1, *cp2; ! 317: char prbuf[100]; ! 318: ! 319: if (argc == 1) { ! 320: printf("Usage: disable {all | printer ...}\n"); ! 321: return; ! 322: } ! 323: if (argc == 2 && !strcmp(argv[1], "all")) { ! 324: printer = prbuf; ! 325: while (getprent(line) > 0) { ! 326: cp1 = prbuf; ! 327: cp2 = line; ! 328: while ((c = *cp2++) && c != '|' && c != ':') ! 329: *cp1++ = c; ! 330: *cp1 = '\0'; ! 331: disablepr(); ! 332: } ! 333: return; ! 334: } ! 335: while (--argc) { ! 336: printer = *++argv; ! 337: if ((status = pgetent(line, printer)) < 0) { ! 338: printf("cannot open printer description file\n"); ! 339: continue; ! 340: } else if (status == 0) { ! 341: printf("unknown printer %s\n", printer); ! 342: continue; ! 343: } ! 344: disablepr(); ! 345: } ! 346: } ! 347: ! 348: disablepr() ! 349: { ! 350: register int fd; ! 351: struct stat stbuf; ! 352: ! 353: bp = pbuf; ! 354: if ((SD = pgetstr("sd", &bp)) == NULL) ! 355: SD = DEFSPOOL; ! 356: if ((LO = pgetstr("lo", &bp)) == NULL) ! 357: LO = DEFLOCK; ! 358: (void) sprintf(line, "%s/%s", SD, LO); ! 359: printf("%s:\n", printer); ! 360: /* ! 361: * Turn on the group execute bit of the lock file to disable queuing. ! 362: */ ! 363: if (stat(line, &stbuf) >= 0) { ! 364: if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) ! 365: printf("\tcannot disable queuing\n"); ! 366: else ! 367: printf("\tqueuing disabled\n"); ! 368: } else if (errno == ENOENT) { ! 369: if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) ! 370: printf("\tcannot create lock file\n"); ! 371: else { ! 372: (void) close(fd); ! 373: printf("\tqueuing disabled\n"); ! 374: } ! 375: return; ! 376: } else ! 377: printf("\tcannot stat lock file\n"); ! 378: } ! 379: ! 380: /* ! 381: * Disable queuing and printing and put a message into the status file ! 382: * (reason for being down). ! 383: */ ! 384: down(argc, argv) ! 385: char *argv[]; ! 386: { ! 387: register int c, status; ! 388: register char *cp1, *cp2; ! 389: char prbuf[100]; ! 390: ! 391: if (argc == 1) { ! 392: printf("Usage: down {all | printer} [message ...]\n"); ! 393: return; ! 394: } ! 395: if (!strcmp(argv[1], "all")) { ! 396: printer = prbuf; ! 397: while (getprent(line) > 0) { ! 398: cp1 = prbuf; ! 399: cp2 = line; ! 400: while ((c = *cp2++) && c != '|' && c != ':') ! 401: *cp1++ = c; ! 402: *cp1 = '\0'; ! 403: putmsg(argc - 2, argv + 2); ! 404: } ! 405: return; ! 406: } ! 407: printer = argv[1]; ! 408: if ((status = pgetent(line, printer)) < 0) { ! 409: printf("cannot open printer description file\n"); ! 410: return; ! 411: } else if (status == 0) { ! 412: printf("unknown printer %s\n", printer); ! 413: return; ! 414: } ! 415: putmsg(argc - 2, argv + 2); ! 416: } ! 417: ! 418: putmsg(argc, argv) ! 419: char **argv; ! 420: { ! 421: register int fd; ! 422: register char *cp1, *cp2; ! 423: char buf[1024]; ! 424: struct stat stbuf; ! 425: ! 426: bp = pbuf; ! 427: if ((SD = pgetstr("sd", &bp)) == NULL) ! 428: SD = DEFSPOOL; ! 429: if ((LO = pgetstr("lo", &bp)) == NULL) ! 430: LO = DEFLOCK; ! 431: if ((ST = pgetstr("st", &bp)) == NULL) ! 432: ST = DEFSTAT; ! 433: printf("%s:\n", printer); ! 434: /* ! 435: * Turn on the group execute bit of the lock file to disable queuing and ! 436: * turn on the owner execute bit of the lock file to disable printing. ! 437: */ ! 438: (void) sprintf(line, "%s/%s", SD, LO); ! 439: if (stat(line, &stbuf) >= 0) { ! 440: if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) ! 441: printf("\tcannot disable queuing\n"); ! 442: else ! 443: printf("\tprinter and queuing disabled\n"); ! 444: } else if (errno == ENOENT) { ! 445: if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) ! 446: printf("\tcannot create lock file\n"); ! 447: else { ! 448: (void) close(fd); ! 449: printf("\tprinter and queuing disabled\n"); ! 450: } ! 451: return; ! 452: } else ! 453: printf("\tcannot stat lock file\n"); ! 454: /* ! 455: * Write the message into the status file. ! 456: */ ! 457: (void) sprintf(line, "%s/%s", SD, ST); ! 458: fd = open(line, O_WRONLY|O_CREAT, 0664); ! 459: if (fd < 0 || flock(fd, LOCK_EX) < 0) { ! 460: printf("\tcannot create status file\n"); ! 461: return; ! 462: } ! 463: (void) ftruncate(fd, 0); ! 464: if (argc <= 0) { ! 465: (void) write(fd, "\n", 1); ! 466: (void) close(fd); ! 467: return; ! 468: } ! 469: cp1 = buf; ! 470: while (--argc >= 0) { ! 471: cp2 = *argv++; ! 472: while (*cp1++ = *cp2++) ! 473: ; ! 474: cp1[-1] = ' '; ! 475: } ! 476: cp1[-1] = '\n'; ! 477: *cp1 = '\0'; ! 478: (void) write(fd, buf, strlen(buf)); ! 479: (void) close(fd); ! 480: } ! 481: ! 482: /* ! 483: * Exit lpc ! 484: */ ! 485: quit(argc, argv) ! 486: char *argv[]; ! 487: { ! 488: exit(0); ! 489: } ! 490: ! 491: /* ! 492: * Kill and restart the daemon. ! 493: */ ! 494: restart(argc, argv) ! 495: char *argv[]; ! 496: { ! 497: register int c, status; ! 498: register char *cp1, *cp2; ! 499: char prbuf[100]; ! 500: ! 501: if (argc == 1) { ! 502: printf("Usage: restart {all | printer ...}\n"); ! 503: return; ! 504: } ! 505: if (argc == 2 && !strcmp(argv[1], "all")) { ! 506: printer = prbuf; ! 507: while (getprent(line) > 0) { ! 508: cp1 = prbuf; ! 509: cp2 = line; ! 510: while ((c = *cp2++) && c != '|' && c != ':') ! 511: *cp1++ = c; ! 512: *cp1 = '\0'; ! 513: abortpr(0); ! 514: startpr(0); ! 515: } ! 516: return; ! 517: } ! 518: while (--argc) { ! 519: printer = *++argv; ! 520: if ((status = pgetent(line, printer)) < 0) { ! 521: printf("cannot open printer description file\n"); ! 522: continue; ! 523: } else if (status == 0) { ! 524: printf("unknown printer %s\n", printer); ! 525: continue; ! 526: } ! 527: abortpr(0); ! 528: startpr(0); ! 529: } ! 530: } ! 531: ! 532: /* ! 533: * Enable printing on the specified printer and startup the daemon. ! 534: */ ! 535: start(argc, argv) ! 536: char *argv[]; ! 537: { ! 538: register int c, status; ! 539: register char *cp1, *cp2; ! 540: char prbuf[100]; ! 541: ! 542: if (argc == 1) { ! 543: printf("Usage: start {all | printer ...}\n"); ! 544: return; ! 545: } ! 546: if (argc == 2 && !strcmp(argv[1], "all")) { ! 547: printer = prbuf; ! 548: while (getprent(line) > 0) { ! 549: cp1 = prbuf; ! 550: cp2 = line; ! 551: while ((c = *cp2++) && c != '|' && c != ':') ! 552: *cp1++ = c; ! 553: *cp1 = '\0'; ! 554: startpr(1); ! 555: } ! 556: return; ! 557: } ! 558: while (--argc) { ! 559: printer = *++argv; ! 560: if ((status = pgetent(line, printer)) < 0) { ! 561: printf("cannot open printer description file\n"); ! 562: continue; ! 563: } else if (status == 0) { ! 564: printf("unknown printer %s\n", printer); ! 565: continue; ! 566: } ! 567: startpr(1); ! 568: } ! 569: } ! 570: ! 571: startpr(enable) ! 572: { ! 573: struct stat stbuf; ! 574: ! 575: bp = pbuf; ! 576: if ((SD = pgetstr("sd", &bp)) == NULL) ! 577: SD = DEFSPOOL; ! 578: if ((LO = pgetstr("lo", &bp)) == NULL) ! 579: LO = DEFLOCK; ! 580: (void) sprintf(line, "%s/%s", SD, LO); ! 581: printf("%s:\n", printer); ! 582: ! 583: /* ! 584: * Turn off the owner execute bit of the lock file to enable printing. ! 585: */ ! 586: if (enable && stat(line, &stbuf) >= 0) { ! 587: if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) ! 588: printf("\tcannot enable printing\n"); ! 589: else ! 590: printf("\tprinting enabled\n"); ! 591: } ! 592: if (!startdaemon(printer)) ! 593: printf("\tcouldn't start daemon\n"); ! 594: else ! 595: printf("\tdaemon started\n"); ! 596: } ! 597: ! 598: /* ! 599: * Print the status of each queue listed or all the queues. ! 600: */ ! 601: status(argc, argv) ! 602: char *argv[]; ! 603: { ! 604: register int c, status; ! 605: register char *cp1, *cp2; ! 606: char prbuf[100]; ! 607: ! 608: if (argc == 1) { ! 609: printer = prbuf; ! 610: while (getprent(line) > 0) { ! 611: cp1 = prbuf; ! 612: cp2 = line; ! 613: while ((c = *cp2++) && c != '|' && c != ':') ! 614: *cp1++ = c; ! 615: *cp1 = '\0'; ! 616: prstat(); ! 617: } ! 618: return; ! 619: } ! 620: while (--argc) { ! 621: printer = *++argv; ! 622: if ((status = pgetent(line, printer)) < 0) { ! 623: printf("cannot open printer description file\n"); ! 624: continue; ! 625: } else if (status == 0) { ! 626: printf("unknown printer %s\n", printer); ! 627: continue; ! 628: } ! 629: prstat(); ! 630: } ! 631: } ! 632: ! 633: /* ! 634: * Print the status of the printer queue. ! 635: */ ! 636: prstat() ! 637: { ! 638: struct stat stbuf; ! 639: register int fd, i; ! 640: register struct direct *dp; ! 641: DIR *dirp; ! 642: ! 643: bp = pbuf; ! 644: if ((SD = pgetstr("sd", &bp)) == NULL) ! 645: SD = DEFSPOOL; ! 646: if ((LO = pgetstr("lo", &bp)) == NULL) ! 647: LO = DEFLOCK; ! 648: if ((ST = pgetstr("st", &bp)) == NULL) ! 649: ST = DEFSTAT; ! 650: printf("%s:\n", printer); ! 651: (void) sprintf(line, "%s/%s", SD, LO); ! 652: if (stat(line, &stbuf) >= 0) { ! 653: printf("\tqueuing is %s\n", ! 654: (stbuf.st_mode & 010) ? "disabled" : "enabled"); ! 655: printf("\tprinting is %s\n", ! 656: (stbuf.st_mode & 0100) ? "disabled" : "enabled"); ! 657: } else { ! 658: printf("\tqueuing is enabled\n"); ! 659: printf("\tprinting is enabled\n"); ! 660: } ! 661: if ((dirp = opendir(SD)) == NULL) { ! 662: printf("\tcannot examine spool directory\n"); ! 663: return; ! 664: } ! 665: i = 0; ! 666: while ((dp = readdir(dirp)) != NULL) { ! 667: if (*dp->d_name == 'c' && dp->d_name[1] == 'f') ! 668: i++; ! 669: } ! 670: closedir(dirp); ! 671: if (i == 0) ! 672: printf("\tno entries\n"); ! 673: else if (i == 1) ! 674: printf("\t1 entry in spool area\n"); ! 675: else ! 676: printf("\t%d entries in spool area\n", i); ! 677: fd = open(line, O_RDONLY); ! 678: if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { ! 679: (void) close(fd); /* unlocks as well */ ! 680: printf("\tno daemon present\n"); ! 681: return; ! 682: } ! 683: (void) close(fd); ! 684: putchar('\t'); ! 685: (void) sprintf(line, "%s/%s", SD, ST); ! 686: fd = open(line, O_RDONLY); ! 687: if (fd >= 0) { ! 688: (void) flock(fd, LOCK_SH); ! 689: while ((i = read(fd, line, sizeof(line))) > 0) ! 690: (void) fwrite(line, 1, i, stdout); ! 691: (void) close(fd); /* unlocks as well */ ! 692: } ! 693: } ! 694: ! 695: /* ! 696: * Stop the specified daemon after completing the current job and disable ! 697: * printing. ! 698: */ ! 699: stop(argc, argv) ! 700: char *argv[]; ! 701: { ! 702: register int c, status; ! 703: register char *cp1, *cp2; ! 704: char prbuf[100]; ! 705: ! 706: if (argc == 1) { ! 707: printf("Usage: stop {all | printer ...}\n"); ! 708: return; ! 709: } ! 710: if (argc == 2 && !strcmp(argv[1], "all")) { ! 711: printer = prbuf; ! 712: while (getprent(line) > 0) { ! 713: cp1 = prbuf; ! 714: cp2 = line; ! 715: while ((c = *cp2++) && c != '|' && c != ':') ! 716: *cp1++ = c; ! 717: *cp1 = '\0'; ! 718: stoppr(); ! 719: } ! 720: return; ! 721: } ! 722: while (--argc) { ! 723: printer = *++argv; ! 724: if ((status = pgetent(line, printer)) < 0) { ! 725: printf("cannot open printer description file\n"); ! 726: continue; ! 727: } else if (status == 0) { ! 728: printf("unknown printer %s\n", printer); ! 729: continue; ! 730: } ! 731: stoppr(); ! 732: } ! 733: } ! 734: ! 735: stoppr() ! 736: { ! 737: register int fd; ! 738: struct stat stbuf; ! 739: ! 740: bp = pbuf; ! 741: if ((SD = pgetstr("sd", &bp)) == NULL) ! 742: SD = DEFSPOOL; ! 743: if ((LO = pgetstr("lo", &bp)) == NULL) ! 744: LO = DEFLOCK; ! 745: (void) sprintf(line, "%s/%s", SD, LO); ! 746: printf("%s:\n", printer); ! 747: ! 748: /* ! 749: * Turn on the owner execute bit of the lock file to disable printing. ! 750: */ ! 751: if (stat(line, &stbuf) >= 0) { ! 752: if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) ! 753: printf("\tcannot disable printing\n"); ! 754: else ! 755: printf("\tprinting disabled\n"); ! 756: } else if (errno == ENOENT) { ! 757: if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) ! 758: printf("\tcannot create lock file\n"); ! 759: else { ! 760: (void) close(fd); ! 761: printf("\tprinting disabled\n"); ! 762: } ! 763: } else ! 764: printf("\tcannot stat lock file\n"); ! 765: } ! 766: ! 767: struct queue **queue; ! 768: int nitems; ! 769: time_t mtime; ! 770: ! 771: /* ! 772: * Put the specified jobs at the top of printer queue. ! 773: */ ! 774: topq(argc, argv) ! 775: char *argv[]; ! 776: { ! 777: register int n, i; ! 778: struct stat stbuf; ! 779: register char *cfname; ! 780: int status, changed; ! 781: ! 782: if (argc < 3) { ! 783: printf("Usage: topq printer [jobnum ...] [user ...]\n"); ! 784: return; ! 785: } ! 786: ! 787: --argc; ! 788: printer = *++argv; ! 789: status = pgetent(line, printer); ! 790: if (status < 0) { ! 791: printf("cannot open printer description file\n"); ! 792: return; ! 793: } else if (status == 0) { ! 794: printf("%s: unknown printer\n", printer); ! 795: return; ! 796: } ! 797: bp = pbuf; ! 798: if ((SD = pgetstr("sd", &bp)) == NULL) ! 799: SD = DEFSPOOL; ! 800: if ((LO = pgetstr("lo", &bp)) == NULL) ! 801: LO = DEFLOCK; ! 802: printf("%s:\n", printer); ! 803: ! 804: if (chdir(SD) < 0) { ! 805: printf("\tcannot chdir to %s\n", SD); ! 806: return; ! 807: } ! 808: nitems = getq(&queue); ! 809: if (nitems == 0) ! 810: return; ! 811: changed = 0; ! 812: mtime = queue[0]->q_time; ! 813: for (i = argc; --i; ) { ! 814: if (doarg(argv[i]) == 0) { ! 815: printf("\tjob %s is not in the queue\n", argv[i]); ! 816: continue; ! 817: } else ! 818: changed++; ! 819: } ! 820: for (i = 0; i < nitems; i++) ! 821: free(queue[i]); ! 822: free(queue); ! 823: if (!changed) { ! 824: printf("\tqueue order unchanged\n"); ! 825: return; ! 826: } ! 827: /* ! 828: * Turn on the public execute bit of the lock file to ! 829: * get lpd to rebuild the queue after the current job. ! 830: */ ! 831: if (changed && stat(LO, &stbuf) >= 0) ! 832: (void) chmod(LO, (stbuf.st_mode & 0777) | 01); ! 833: } ! 834: ! 835: /* ! 836: * Reposition the job by changing the modification time of ! 837: * the control file. ! 838: */ ! 839: touch(q) ! 840: struct queue *q; ! 841: { ! 842: struct timeval tvp[2]; ! 843: ! 844: tvp[0].tv_sec = tvp[1].tv_sec = --mtime; ! 845: tvp[0].tv_usec = tvp[1].tv_usec = 0; ! 846: return(utimes(q->q_name, tvp)); ! 847: } ! 848: ! 849: /* ! 850: * Checks if specified job name is in the printer's queue. ! 851: * Returns: negative (-1) if argument name is not in the queue. ! 852: */ ! 853: doarg(job) ! 854: char *job; ! 855: { ! 856: register struct queue **qq; ! 857: register int jobnum, n; ! 858: register char *cp, *machine; ! 859: int cnt = 0; ! 860: FILE *fp; ! 861: ! 862: /* ! 863: * Look for a job item consisting of system name, colon, number ! 864: * (example: ucbarpa:114) ! 865: */ ! 866: if ((cp = index(job, ':')) != NULL) { ! 867: machine = job; ! 868: *cp++ = '\0'; ! 869: job = cp; ! 870: } else ! 871: machine = NULL; ! 872: ! 873: /* ! 874: * Check for job specified by number (example: 112 or 235ucbarpa). ! 875: */ ! 876: if (isdigit(*job)) { ! 877: jobnum = 0; ! 878: do ! 879: jobnum = jobnum * 10 + (*job++ - '0'); ! 880: while (isdigit(*job)); ! 881: for (qq = queue + nitems; --qq >= queue; ) { ! 882: n = 0; ! 883: for (cp = (*qq)->q_name+3; isdigit(*cp); ) ! 884: n = n * 10 + (*cp++ - '0'); ! 885: if (jobnum != n) ! 886: continue; ! 887: if (*job && strcmp(job, cp) != 0) ! 888: continue; ! 889: if (machine != NULL && strcmp(machine, cp) != 0) ! 890: continue; ! 891: if (touch(*qq) == 0) { ! 892: printf("\tmoved %s\n", (*qq)->q_name); ! 893: cnt++; ! 894: } ! 895: } ! 896: return(cnt); ! 897: } ! 898: /* ! 899: * Process item consisting of owner's name (example: henry). ! 900: */ ! 901: for (qq = queue + nitems; --qq >= queue; ) { ! 902: if ((fp = fopen((*qq)->q_name, "r")) == NULL) ! 903: continue; ! 904: while (getline(fp) > 0) ! 905: if (line[0] == 'P') ! 906: break; ! 907: (void) fclose(fp); ! 908: if (line[0] != 'P' || strcmp(job, line+1) != 0) ! 909: continue; ! 910: if (touch(*qq) == 0) { ! 911: printf("\tmoved %s\n", (*qq)->q_name); ! 912: cnt++; ! 913: } ! 914: } ! 915: return(cnt); ! 916: } ! 917: ! 918: /* ! 919: * Enable everything and start printer (undo `down'). ! 920: */ ! 921: up(argc, argv) ! 922: char *argv[]; ! 923: { ! 924: register int c, status; ! 925: register char *cp1, *cp2; ! 926: char prbuf[100]; ! 927: ! 928: if (argc == 1) { ! 929: printf("Usage: up {all | printer ...}\n"); ! 930: return; ! 931: } ! 932: if (argc == 2 && !strcmp(argv[1], "all")) { ! 933: printer = prbuf; ! 934: while (getprent(line) > 0) { ! 935: cp1 = prbuf; ! 936: cp2 = line; ! 937: while ((c = *cp2++) && c != '|' && c != ':') ! 938: *cp1++ = c; ! 939: *cp1 = '\0'; ! 940: startpr(2); ! 941: } ! 942: return; ! 943: } ! 944: while (--argc) { ! 945: printer = *++argv; ! 946: if ((status = pgetent(line, printer)) < 0) { ! 947: printf("cannot open printer description file\n"); ! 948: continue; ! 949: } else if (status == 0) { ! 950: printf("unknown printer %s\n", printer); ! 951: continue; ! 952: } ! 953: startpr(2); ! 954: } ! 955: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.