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: }

Defined functions

abort defined in line 21; used 2 times
abortpr defined in line 57; used 4 times
clean defined in line 116; used 2 times
cleanpr defined in line 187; used 2 times
disable defined in line 312; used 2 times
disablepr defined in line 348; used 2 times
doarg defined in line 853; used 1 times
down defined in line 384; used 2 times
enable defined in line 250; used 5 times
enablepr defined in line 286; used 2 times
prstat defined in line 636; used 2 times
putmsg defined in line 418; used 2 times
restart defined in line 494; used 2 times
select defined in line 152; used 83 times
sortq defined in line 166; used 1 times
start defined in line 535; used 2 times
startpr defined in line 571; used 6 times
stop defined in line 699; used 2 times
stoppr defined in line 735; used 2 times
topq defined in line 774; used 2 times
touch defined in line 839; used 2 times
unlinkf defined in line 238; used 2 times
up defined in line 921; used 2 times

Defined variables

nitems defined in line 768; used 11 times
queue defined in line 767; used 12 times
sccsid defined in line 8; never used
Last modified: 1986-03-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2894
Valid CSS Valid XHTML 1.0 Strict