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