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