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