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) 03/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 } 956