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