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.1 (Berkeley) 06/06/85"; 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 gethostname(host, sizeof(host)); 506 if (argc == 2 && !strcmp(argv[1], "all")) { 507 printer = prbuf; 508 while (getprent(line) > 0) { 509 cp1 = prbuf; 510 cp2 = line; 511 while ((c = *cp2++) && c != '|' && c != ':') 512 *cp1++ = c; 513 *cp1 = '\0'; 514 abortpr(0); 515 startpr(0); 516 } 517 return; 518 } 519 while (--argc) { 520 printer = *++argv; 521 if ((status = pgetent(line, printer)) < 0) { 522 printf("cannot open printer description file\n"); 523 continue; 524 } else if (status == 0) { 525 printf("unknown printer %s\n", printer); 526 continue; 527 } 528 abortpr(0); 529 startpr(0); 530 } 531 } 532 533 /* 534 * Enable printing on the specified printer and startup the daemon. 535 */ 536 start(argc, argv) 537 char *argv[]; 538 { 539 register int c, status; 540 register char *cp1, *cp2; 541 char prbuf[100]; 542 543 if (argc == 1) { 544 printf("Usage: start {all | printer ...}\n"); 545 return; 546 } 547 gethostname(host, sizeof(host)); 548 if (argc == 2 && !strcmp(argv[1], "all")) { 549 printer = prbuf; 550 while (getprent(line) > 0) { 551 cp1 = prbuf; 552 cp2 = line; 553 while ((c = *cp2++) && c != '|' && c != ':') 554 *cp1++ = c; 555 *cp1 = '\0'; 556 startpr(1); 557 } 558 return; 559 } 560 while (--argc) { 561 printer = *++argv; 562 if ((status = pgetent(line, printer)) < 0) { 563 printf("cannot open printer description file\n"); 564 continue; 565 } else if (status == 0) { 566 printf("unknown printer %s\n", printer); 567 continue; 568 } 569 startpr(1); 570 } 571 } 572 573 startpr(enable) 574 { 575 struct stat stbuf; 576 577 bp = pbuf; 578 if ((SD = pgetstr("sd", &bp)) == NULL) 579 SD = DEFSPOOL; 580 if ((LO = pgetstr("lo", &bp)) == NULL) 581 LO = DEFLOCK; 582 (void) sprintf(line, "%s/%s", SD, LO); 583 printf("%s:\n", printer); 584 585 /* 586 * Turn off the owner execute bit of the lock file to enable printing. 587 */ 588 if (enable && stat(line, &stbuf) >= 0) { 589 if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 590 printf("\tcannot enable printing\n"); 591 else 592 printf("\tprinting enabled\n"); 593 } 594 if (!startdaemon(printer)) 595 printf("\tcouldn't start daemon\n"); 596 else 597 printf("\tdaemon started\n"); 598 } 599 600 /* 601 * Print the status of each queue listed or all the queues. 602 */ 603 status(argc, argv) 604 char *argv[]; 605 { 606 register int c, status; 607 register char *cp1, *cp2; 608 char prbuf[100]; 609 610 if (argc == 1) { 611 printer = prbuf; 612 while (getprent(line) > 0) { 613 cp1 = prbuf; 614 cp2 = line; 615 while ((c = *cp2++) && c != '|' && c != ':') 616 *cp1++ = c; 617 *cp1 = '\0'; 618 prstat(); 619 } 620 return; 621 } 622 while (--argc) { 623 printer = *++argv; 624 if ((status = pgetent(line, printer)) < 0) { 625 printf("cannot open printer description file\n"); 626 continue; 627 } else if (status == 0) { 628 printf("unknown printer %s\n", printer); 629 continue; 630 } 631 prstat(); 632 } 633 } 634 635 /* 636 * Print the status of the printer queue. 637 */ 638 prstat() 639 { 640 struct stat stbuf; 641 register int fd, i; 642 register struct direct *dp; 643 DIR *dirp; 644 645 bp = pbuf; 646 if ((SD = pgetstr("sd", &bp)) == NULL) 647 SD = DEFSPOOL; 648 if ((LO = pgetstr("lo", &bp)) == NULL) 649 LO = DEFLOCK; 650 if ((ST = pgetstr("st", &bp)) == NULL) 651 ST = DEFSTAT; 652 printf("%s:\n", printer); 653 (void) sprintf(line, "%s/%s", SD, LO); 654 if (stat(line, &stbuf) >= 0) { 655 printf("\tqueuing is %s\n", 656 (stbuf.st_mode & 010) ? "disabled" : "enabled"); 657 printf("\tprinting is %s\n", 658 (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 659 } else { 660 printf("\tqueuing is enabled\n"); 661 printf("\tprinting is enabled\n"); 662 } 663 if ((dirp = opendir(SD)) == NULL) { 664 printf("\tcannot examine spool directory\n"); 665 return; 666 } 667 i = 0; 668 while ((dp = readdir(dirp)) != NULL) { 669 if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 670 i++; 671 } 672 closedir(dirp); 673 if (i == 0) 674 printf("\tno entries\n"); 675 else if (i == 1) 676 printf("\t1 entry in spool area\n"); 677 else 678 printf("\t%d entries in spool area\n", i); 679 fd = open(line, O_RDONLY); 680 if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 681 (void) close(fd); /* unlocks as well */ 682 printf("\tno daemon present\n"); 683 return; 684 } 685 (void) close(fd); 686 putchar('\t'); 687 (void) sprintf(line, "%s/%s", SD, ST); 688 fd = open(line, O_RDONLY); 689 if (fd >= 0) { 690 (void) flock(fd, LOCK_SH); 691 while ((i = read(fd, line, sizeof(line))) > 0) 692 (void) fwrite(line, 1, i, stdout); 693 (void) close(fd); /* unlocks as well */ 694 } 695 } 696 697 /* 698 * Stop the specified daemon after completing the current job and disable 699 * printing. 700 */ 701 stop(argc, argv) 702 char *argv[]; 703 { 704 register int c, status; 705 register char *cp1, *cp2; 706 char prbuf[100]; 707 708 if (argc == 1) { 709 printf("Usage: stop {all | printer ...}\n"); 710 return; 711 } 712 if (argc == 2 && !strcmp(argv[1], "all")) { 713 printer = prbuf; 714 while (getprent(line) > 0) { 715 cp1 = prbuf; 716 cp2 = line; 717 while ((c = *cp2++) && c != '|' && c != ':') 718 *cp1++ = c; 719 *cp1 = '\0'; 720 stoppr(); 721 } 722 return; 723 } 724 while (--argc) { 725 printer = *++argv; 726 if ((status = pgetent(line, printer)) < 0) { 727 printf("cannot open printer description file\n"); 728 continue; 729 } else if (status == 0) { 730 printf("unknown printer %s\n", printer); 731 continue; 732 } 733 stoppr(); 734 } 735 } 736 737 stoppr() 738 { 739 register int fd; 740 struct stat stbuf; 741 742 bp = pbuf; 743 if ((SD = pgetstr("sd", &bp)) == NULL) 744 SD = DEFSPOOL; 745 if ((LO = pgetstr("lo", &bp)) == NULL) 746 LO = DEFLOCK; 747 (void) sprintf(line, "%s/%s", SD, LO); 748 printf("%s:\n", printer); 749 750 /* 751 * Turn on the owner execute bit of the lock file to disable printing. 752 */ 753 if (stat(line, &stbuf) >= 0) { 754 if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 755 printf("\tcannot disable printing\n"); 756 else 757 printf("\tprinting disabled\n"); 758 } else if (errno == ENOENT) { 759 if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 760 printf("\tcannot create lock file\n"); 761 else { 762 (void) close(fd); 763 printf("\tprinting disabled\n"); 764 } 765 } else 766 printf("\tcannot stat lock file\n"); 767 } 768 769 struct queue **queue; 770 int nitems; 771 time_t mtime; 772 773 /* 774 * Put the specified jobs at the top of printer queue. 775 */ 776 topq(argc, argv) 777 char *argv[]; 778 { 779 register int n, i; 780 struct stat stbuf; 781 register char *cfname; 782 int status, changed; 783 784 if (argc < 3) { 785 printf("Usage: topq printer [jobnum ...] [user ...]\n"); 786 return; 787 } 788 789 --argc; 790 printer = *++argv; 791 status = pgetent(line, printer); 792 if (status < 0) { 793 printf("cannot open printer description file\n"); 794 return; 795 } else if (status == 0) { 796 printf("%s: unknown printer\n", printer); 797 return; 798 } 799 bp = pbuf; 800 if ((SD = pgetstr("sd", &bp)) == NULL) 801 SD = DEFSPOOL; 802 if ((LO = pgetstr("lo", &bp)) == NULL) 803 LO = DEFLOCK; 804 printf("%s:\n", printer); 805 806 if (chdir(SD) < 0) { 807 printf("\tcannot chdir to %s\n", SD); 808 return; 809 } 810 nitems = getq(&queue); 811 if (nitems == 0) 812 return; 813 changed = 0; 814 mtime = queue[0]->q_time; 815 for (i = argc; --i; ) { 816 if (doarg(argv[i]) == 0) { 817 printf("\tjob %s is not in the queue\n", argv[i]); 818 continue; 819 } else 820 changed++; 821 } 822 for (i = 0; i < nitems; i++) 823 free(queue[i]); 824 free(queue); 825 if (!changed) { 826 printf("\tqueue order unchanged\n"); 827 return; 828 } 829 /* 830 * Turn on the public execute bit of the lock file to 831 * get lpd to rebuild the queue after the current job. 832 */ 833 if (changed && stat(LO, &stbuf) >= 0) 834 (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 835 } 836 837 /* 838 * Reposition the job by changing the modification time of 839 * the control file. 840 */ 841 touch(q) 842 struct queue *q; 843 { 844 struct timeval tvp[2]; 845 846 tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 847 tvp[0].tv_usec = tvp[1].tv_usec = 0; 848 return(utimes(q->q_name, tvp)); 849 } 850 851 /* 852 * Checks if specified job name is in the printer's queue. 853 * Returns: negative (-1) if argument name is not in the queue. 854 */ 855 doarg(job) 856 char *job; 857 { 858 register struct queue **qq; 859 register int jobnum, n; 860 register char *cp, *machine; 861 int cnt = 0; 862 FILE *fp; 863 864 /* 865 * Look for a job item consisting of system name, colon, number 866 * (example: ucbarpa:114) 867 */ 868 if ((cp = index(job, ':')) != NULL) { 869 machine = job; 870 *cp++ = '\0'; 871 job = cp; 872 } else 873 machine = NULL; 874 875 /* 876 * Check for job specified by number (example: 112 or 235ucbarpa). 877 */ 878 if (isdigit(*job)) { 879 jobnum = 0; 880 do 881 jobnum = jobnum * 10 + (*job++ - '0'); 882 while (isdigit(*job)); 883 for (qq = queue + nitems; --qq >= queue; ) { 884 n = 0; 885 for (cp = (*qq)->q_name+3; isdigit(*cp); ) 886 n = n * 10 + (*cp++ - '0'); 887 if (jobnum != n) 888 continue; 889 if (*job && strcmp(job, cp) != 0) 890 continue; 891 if (machine != NULL && strcmp(machine, cp) != 0) 892 continue; 893 if (touch(*qq) == 0) { 894 printf("\tmoved %s\n", (*qq)->q_name); 895 cnt++; 896 } 897 } 898 return(cnt); 899 } 900 /* 901 * Process item consisting of owner's name (example: henry). 902 */ 903 for (qq = queue + nitems; --qq >= queue; ) { 904 if ((fp = fopen((*qq)->q_name, "r")) == NULL) 905 continue; 906 while (getline(fp) > 0) 907 if (line[0] == 'P') 908 break; 909 (void) fclose(fp); 910 if (line[0] != 'P' || strcmp(job, line+1) != 0) 911 continue; 912 if (touch(*qq) == 0) { 913 printf("\tmoved %s\n", (*qq)->q_name); 914 cnt++; 915 } 916 } 917 return(cnt); 918 } 919 920 /* 921 * Enable everything and start printer (undo `down'). 922 */ 923 up(argc, argv) 924 char *argv[]; 925 { 926 register int c, status; 927 register char *cp1, *cp2; 928 char prbuf[100]; 929 930 if (argc == 1) { 931 printf("Usage: up {all | printer ...}\n"); 932 return; 933 } 934 if (argc == 2 && !strcmp(argv[1], "all")) { 935 printer = prbuf; 936 while (getprent(line) > 0) { 937 cp1 = prbuf; 938 cp2 = line; 939 while ((c = *cp2++) && c != '|' && c != ':') 940 *cp1++ = c; 941 *cp1 = '\0'; 942 startpr(2); 943 } 944 return; 945 } 946 while (--argc) { 947 printer = *++argv; 948 if ((status = pgetent(line, printer)) < 0) { 949 printf("cannot open printer description file\n"); 950 continue; 951 } else if (status == 0) { 952 printf("unknown printer %s\n", printer); 953 continue; 954 } 955 startpr(2); 956 } 957 } 958