112382Sralph #ifndef lint 2*15907Sralph static char sccsid[] = "@(#)cmds.c 4.10 (Berkeley) 01/30/84"; 312382Sralph #endif 412382Sralph 512382Sralph /* 615719Sralph * lpc -- line printer control program -- commands: 712382Sralph */ 812382Sralph 912382Sralph #include "lp.h" 1015719Sralph #include <sys/time.h> 1112382Sralph 1212382Sralph /* 1312382Sralph * kill an existing daemon and disable printing. 1412382Sralph */ 1512382Sralph abort(argc, argv) 1612382Sralph char *argv[]; 1712382Sralph { 1812382Sralph register int c, status; 1912382Sralph register char *cp1, *cp2; 2012382Sralph char prbuf[100]; 2112382Sralph 2212382Sralph if (argc == 1) { 2312382Sralph printf("Usage: abort {all | printer ...}\n"); 2412382Sralph return; 2512382Sralph } 2612382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 2712382Sralph printer = prbuf; 2812382Sralph while (getprent(line) > 0) { 2912382Sralph cp1 = prbuf; 3012382Sralph cp2 = line; 3112382Sralph while ((c = *cp2++) && c != '|' && c != ':') 3212382Sralph *cp1++ = c; 3312382Sralph *cp1 = '\0'; 3412382Sralph abortpr(); 3512382Sralph } 3612382Sralph return; 3712382Sralph } 3812382Sralph while (--argc) { 3912382Sralph printer = *++argv; 4012382Sralph if ((status = pgetent(line, printer)) < 0) { 4112514Sralph printf("cannot open printer description file\n"); 4212382Sralph continue; 4312382Sralph } else if (status == 0) { 4412514Sralph printf("unknown printer %s\n", printer); 4512382Sralph continue; 4612382Sralph } 4712382Sralph abortpr(); 4812382Sralph } 4912382Sralph } 5012382Sralph 5112382Sralph abortpr() 5212382Sralph { 5312382Sralph register FILE *fp; 5412382Sralph struct stat stbuf; 5512382Sralph int pid, fd; 5612382Sralph 5712382Sralph bp = pbuf; 5812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 5912382Sralph SD = DEFSPOOL; 6012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 6112382Sralph LO = DEFLOCK; 6212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 6312382Sralph printf("%s:\n", printer); 6412382Sralph 6512382Sralph /* 6612382Sralph * Turn on the owner execute bit of the lock file to disable printing. 6712382Sralph */ 6812382Sralph if (stat(line, &stbuf) >= 0) { 6912382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 7012382Sralph printf("\tcannot disable printing\n"); 7112382Sralph else 7212382Sralph printf("\tprinting disabled\n"); 7312382Sralph } else if (errno == ENOENT) { 7413146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 7512514Sralph printf("\tcannot create lock file\n"); 7612382Sralph else { 7712382Sralph (void) close(fd); 7812382Sralph printf("\tprinting disabled\n"); 7912382Sralph printf("\tno daemon to abort\n"); 8012382Sralph } 8112382Sralph return; 8212382Sralph } else { 8312382Sralph printf("\tcannot stat lock file\n"); 8412382Sralph return; 8512382Sralph } 8612382Sralph /* 8712382Sralph * Kill the current daemon to stop printing now. 8812382Sralph */ 8912382Sralph if ((fp = fopen(line, "r")) == NULL) { 9012382Sralph printf("\tcannot open lock file\n"); 9112382Sralph return; 9212382Sralph } 9313146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 9413168Sralph (void) fclose(fp); /* unlocks as well */ 9512382Sralph printf("\tno daemon to abort\n"); 9612382Sralph return; 9712382Sralph } 9812382Sralph (void) fclose(fp); 9912382Sralph if (kill(pid = atoi(line), SIGINT) < 0) 10012382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 10112382Sralph else 10212382Sralph printf("\tdaemon (pid %d) killed\n", pid); 10312382Sralph } 10412382Sralph 10512382Sralph /* 10612382Sralph * Remove all spool files and temporaries from the spooling area. 10712382Sralph */ 10812382Sralph clean(argc, argv) 10912382Sralph char *argv[]; 11012382Sralph { 11112382Sralph register int c, status; 11212382Sralph register char *cp1, *cp2; 11312382Sralph char prbuf[100]; 11412382Sralph 11512382Sralph if (argc == 1) { 11612382Sralph printf("Usage: clean {all | printer ...}\n"); 11712382Sralph return; 11812382Sralph } 11912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 12012382Sralph printer = prbuf; 12112382Sralph while (getprent(line) > 0) { 12212382Sralph cp1 = prbuf; 12312382Sralph cp2 = line; 12412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 12512382Sralph *cp1++ = c; 12612382Sralph *cp1 = '\0'; 12712382Sralph cleanpr(); 12812382Sralph } 12912382Sralph return; 13012382Sralph } 13112382Sralph while (--argc) { 13212382Sralph printer = *++argv; 13312382Sralph if ((status = pgetent(line, printer)) < 0) { 13412514Sralph printf("cannot open printer description file\n"); 13512382Sralph continue; 13612382Sralph } else if (status == 0) { 13712514Sralph printf("unknown printer %s\n", printer); 13812382Sralph continue; 13912382Sralph } 14012382Sralph cleanpr(); 14112382Sralph } 14212382Sralph } 14312382Sralph 14415719Sralph select(d) 14515719Sralph struct direct *d; 14615719Sralph { 14715719Sralph int c = d->d_name[0]; 14815719Sralph 14915719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 15015719Sralph return(1); 15115719Sralph return(0); 15215719Sralph } 15315719Sralph 15415719Sralph /* 15515719Sralph * Comparison routine for scandir. Sort by job number and machine, then 15615719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 15715719Sralph */ 15815719Sralph sortq(d1, d2) 15915719Sralph struct direct **d1, **d2; 16015719Sralph { 16115719Sralph int c1, c2; 16215719Sralph 16315719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 16415719Sralph return(c1); 16515719Sralph c1 = (*d1)->d_name[0]; 16615719Sralph c2 = (*d2)->d_name[0]; 16715719Sralph if (c1 == c2) 16815719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 16915719Sralph if (c1 == 'c') 17015719Sralph return(-1); 17115719Sralph if (c1 == 'd' || c2 == 'c') 17215719Sralph return(1); 17315719Sralph return(-1); 17415719Sralph } 17515719Sralph 17615719Sralph /* 17715719Sralph * Remove incomplete jobs from spooling area. 17815719Sralph */ 17912382Sralph cleanpr() 18012382Sralph { 18115719Sralph register int i, n; 18215719Sralph register char *cp, *cp1, *lp; 18315719Sralph struct direct **queue; 18415719Sralph int nitems; 18512382Sralph 18612382Sralph bp = pbuf; 18712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 18812382Sralph SD = DEFSPOOL; 18912382Sralph printf("%s:\n", printer); 19012382Sralph 19115719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 19215719Sralph ; 19315719Sralph lp[-1] = '/'; 19415719Sralph 19515719Sralph nitems = scandir(SD, &queue, select, sortq); 19615719Sralph if (nitems < 0) { 19712382Sralph printf("\tcannot examine spool directory\n"); 19812382Sralph return; 19912382Sralph } 20015719Sralph if (nitems == 0) 20115719Sralph return; 20215719Sralph i = 0; 20315719Sralph do { 20415719Sralph cp = queue[i]->d_name; 20515719Sralph if (*cp == 'c') { 20615719Sralph n = 0; 20715719Sralph while (i + 1 < nitems) { 20815719Sralph cp1 = queue[i + 1]->d_name; 20915719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 21015719Sralph break; 21115719Sralph i++; 21215719Sralph n++; 21315719Sralph } 21415719Sralph if (n == 0) { 21515719Sralph strcpy(lp, cp); 21615719Sralph unlinkf(line); 21715719Sralph } 21815719Sralph } else { 21915719Sralph /* 22015719Sralph * Must be a df with no cf (otherwise, it would have 22115719Sralph * been skipped above) or a tf file (which can always 22215719Sralph * be removed). 22315719Sralph */ 22415719Sralph strcpy(lp, cp); 22515719Sralph unlinkf(line); 22612382Sralph } 22715719Sralph } while (++i < nitems); 22812382Sralph } 22915719Sralph 23015719Sralph unlinkf(name) 23115719Sralph char *name; 23215719Sralph { 23315719Sralph if (unlink(name) < 0) 23415719Sralph printf("\tcannot remove %s\n", name); 23515719Sralph else 23615719Sralph printf("\tremoved %s\n", name); 23715719Sralph } 23812382Sralph 23912382Sralph /* 24012382Sralph * Enable queuing to the printer (allow lpr's). 24112382Sralph */ 24212382Sralph enable(argc, argv) 24312382Sralph char *argv[]; 24412382Sralph { 24512382Sralph register int c, status; 24612382Sralph register char *cp1, *cp2; 24712382Sralph char prbuf[100]; 24812382Sralph 24912382Sralph if (argc == 1) { 25012382Sralph printf("Usage: enable {all | printer ...}\n"); 25112382Sralph return; 25212382Sralph } 25312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 25412382Sralph printer = prbuf; 25512382Sralph while (getprent(line) > 0) { 25612382Sralph cp1 = prbuf; 25712382Sralph cp2 = line; 25812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 25912382Sralph *cp1++ = c; 26012382Sralph *cp1 = '\0'; 26112382Sralph enablepr(); 26212382Sralph } 26312382Sralph return; 26412382Sralph } 26512382Sralph while (--argc) { 26612382Sralph printer = *++argv; 26712382Sralph if ((status = pgetent(line, printer)) < 0) { 26812514Sralph printf("cannot open printer description file\n"); 26912382Sralph continue; 27012382Sralph } else if (status == 0) { 27112514Sralph printf("unknown printer %s\n", printer); 27212382Sralph continue; 27312382Sralph } 27412382Sralph enablepr(); 27512382Sralph } 27612382Sralph } 27712382Sralph 27812382Sralph enablepr() 27912382Sralph { 28012382Sralph struct stat stbuf; 28112382Sralph 28212382Sralph bp = pbuf; 28312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 28412382Sralph SD = DEFSPOOL; 28512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 28612382Sralph LO = DEFLOCK; 28712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 28812382Sralph printf("%s:\n", printer); 28912382Sralph 29012382Sralph /* 29112382Sralph * Turn off the group execute bit of the lock file to enable queuing. 29212382Sralph */ 29312382Sralph if (stat(line, &stbuf) >= 0) { 29412382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 29512514Sralph printf("\tcannot enable queuing\n"); 29612382Sralph else 29712382Sralph printf("\tqueuing enabled\n"); 29812382Sralph } 29912382Sralph } 30012382Sralph 30112382Sralph /* 30212382Sralph * Disable queuing. 30312382Sralph */ 30412382Sralph disable(argc, argv) 30512382Sralph char *argv[]; 30612382Sralph { 30712382Sralph register int c, status; 30812382Sralph register char *cp1, *cp2; 30912382Sralph char prbuf[100]; 31012382Sralph 31112382Sralph if (argc == 1) { 31212382Sralph printf("Usage: disable {all | printer ...}\n"); 31312382Sralph return; 31412382Sralph } 31512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 31612382Sralph printer = prbuf; 31712382Sralph while (getprent(line) > 0) { 31812382Sralph cp1 = prbuf; 31912382Sralph cp2 = line; 32012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 32112382Sralph *cp1++ = c; 32212382Sralph *cp1 = '\0'; 32312382Sralph disablepr(); 32412382Sralph } 32512382Sralph return; 32612382Sralph } 32712382Sralph while (--argc) { 32812382Sralph printer = *++argv; 32912382Sralph if ((status = pgetent(line, printer)) < 0) { 33012514Sralph printf("cannot open printer description file\n"); 33112382Sralph continue; 33212382Sralph } else if (status == 0) { 33312514Sralph printf("unknown printer %s\n", printer); 33412382Sralph continue; 33512382Sralph } 33612382Sralph disablepr(); 33712382Sralph } 33812382Sralph } 33912382Sralph 34012382Sralph disablepr() 34112382Sralph { 34212382Sralph register int fd; 34312382Sralph struct stat stbuf; 34412382Sralph 34512382Sralph bp = pbuf; 34612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 34712382Sralph SD = DEFSPOOL; 34812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 34912382Sralph LO = DEFLOCK; 35012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 35112382Sralph printf("%s:\n", printer); 35212382Sralph /* 35312382Sralph * Turn on the group execute bit of the lock file to disable queuing. 35412382Sralph */ 35512382Sralph if (stat(line, &stbuf) >= 0) { 35612382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 35712382Sralph printf("\tcannot disable queuing\n"); 35812382Sralph else 35912382Sralph printf("\tqueuing disabled\n"); 36012382Sralph } else if (errno == ENOENT) { 36113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 36212382Sralph printf("\tcannot create lock file\n"); 36312382Sralph else { 36412382Sralph (void) close(fd); 36512382Sralph printf("\tqueuing disabled\n"); 36612382Sralph } 36712382Sralph return; 36812382Sralph } else 36912382Sralph printf("\tcannot stat lock file\n"); 37012382Sralph } 37112382Sralph 37212382Sralph /* 373*15907Sralph * Disable queuing and printing and put a message into the status file 374*15907Sralph * (reason for being down). 375*15907Sralph */ 376*15907Sralph down(argc, argv) 377*15907Sralph char *argv[]; 378*15907Sralph { 379*15907Sralph register int c, status; 380*15907Sralph register char *cp1, *cp2; 381*15907Sralph char prbuf[100]; 382*15907Sralph 383*15907Sralph if (argc == 1) { 384*15907Sralph printf("Usage: disable {all | printer} [message ...]\n"); 385*15907Sralph return; 386*15907Sralph } 387*15907Sralph if (!strcmp(argv[1], "all")) { 388*15907Sralph printer = prbuf; 389*15907Sralph while (getprent(line) > 0) { 390*15907Sralph cp1 = prbuf; 391*15907Sralph cp2 = line; 392*15907Sralph while ((c = *cp2++) && c != '|' && c != ':') 393*15907Sralph *cp1++ = c; 394*15907Sralph *cp1 = '\0'; 395*15907Sralph putmsg(argc - 2, argv + 2); 396*15907Sralph } 397*15907Sralph return; 398*15907Sralph } 399*15907Sralph printer = argv[1]; 400*15907Sralph if ((status = pgetent(line, printer)) < 0) { 401*15907Sralph printf("cannot open printer description file\n"); 402*15907Sralph return; 403*15907Sralph } else if (status == 0) { 404*15907Sralph printf("unknown printer %s\n", printer); 405*15907Sralph return; 406*15907Sralph } 407*15907Sralph putmsg(argc - 2, argv + 2); 408*15907Sralph } 409*15907Sralph 410*15907Sralph putmsg(argc, argv) 411*15907Sralph char **argv; 412*15907Sralph { 413*15907Sralph register int fd; 414*15907Sralph register char *cp1, *cp2; 415*15907Sralph char buf[1024]; 416*15907Sralph struct stat stbuf; 417*15907Sralph 418*15907Sralph bp = pbuf; 419*15907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 420*15907Sralph SD = DEFSPOOL; 421*15907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 422*15907Sralph LO = DEFLOCK; 423*15907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 424*15907Sralph ST = DEFSTAT; 425*15907Sralph printf("%s:\n", printer); 426*15907Sralph /* 427*15907Sralph * Turn on the group execute bit of the lock file to disable queuing and 428*15907Sralph * turn on the owner execute bit of the lock file to disable printing. 429*15907Sralph */ 430*15907Sralph (void) sprintf(line, "%s/%s", SD, LO); 431*15907Sralph if (stat(line, &stbuf) >= 0) { 432*15907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 433*15907Sralph printf("\tcannot disable queuing\n"); 434*15907Sralph else 435*15907Sralph printf("\tprinter and queuing disabled\n"); 436*15907Sralph } else if (errno == ENOENT) { 437*15907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 438*15907Sralph printf("\tcannot create lock file\n"); 439*15907Sralph else { 440*15907Sralph (void) close(fd); 441*15907Sralph printf("\tprinter and queuing disabled\n"); 442*15907Sralph } 443*15907Sralph return; 444*15907Sralph } else 445*15907Sralph printf("\tcannot stat lock file\n"); 446*15907Sralph /* 447*15907Sralph * Write the message into the status file. 448*15907Sralph */ 449*15907Sralph if (argc <= 0) 450*15907Sralph return; 451*15907Sralph (void) sprintf(line, "%s/%s", SD, ST); 452*15907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 453*15907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 454*15907Sralph printf("\tcannot create status file\n"); 455*15907Sralph return; 456*15907Sralph } 457*15907Sralph (void) ftruncate(fd, 0); 458*15907Sralph cp1 = buf; 459*15907Sralph while (--argc >= 0) { 460*15907Sralph cp2 = *argv++; 461*15907Sralph while (*cp1++ = *cp2++) 462*15907Sralph ; 463*15907Sralph cp1[-1] = ' '; 464*15907Sralph } 465*15907Sralph cp1[-1] = '\n'; 466*15907Sralph *cp1 = '\0'; 467*15907Sralph (void) write(fd, buf, strlen(buf)); 468*15907Sralph (void) close(fd); 469*15907Sralph } 470*15907Sralph 471*15907Sralph /* 47212382Sralph * Exit lpc 47312382Sralph */ 47412382Sralph quit(argc, argv) 47512382Sralph char *argv[]; 47612382Sralph { 47712382Sralph exit(0); 47812382Sralph } 47912382Sralph 48012382Sralph /* 48112382Sralph * Startup the daemon. 48212382Sralph */ 48312382Sralph restart(argc, argv) 48412382Sralph char *argv[]; 48512382Sralph { 48612382Sralph register int c, status; 48712382Sralph register char *cp1, *cp2; 48812382Sralph char prbuf[100]; 48912382Sralph 49012382Sralph if (argc == 1) { 49112382Sralph printf("Usage: restart {all | printer ...}\n"); 49212382Sralph return; 49312382Sralph } 49412382Sralph gethostname(host, sizeof(host)); 49512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 49612382Sralph printer = prbuf; 49712382Sralph while (getprent(line) > 0) { 49812382Sralph cp1 = prbuf; 49912382Sralph cp2 = line; 50012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 50112382Sralph *cp1++ = c; 50212382Sralph *cp1 = '\0'; 50312382Sralph startpr(0); 50412382Sralph } 50512382Sralph return; 50612382Sralph } 50712382Sralph while (--argc) { 50812382Sralph printer = *++argv; 50912382Sralph if ((status = pgetent(line, printer)) < 0) { 51012514Sralph printf("cannot open printer description file\n"); 51112382Sralph continue; 51212382Sralph } else if (status == 0) { 51312514Sralph printf("unknown printer %s\n", printer); 51412382Sralph continue; 51512382Sralph } 51612382Sralph startpr(0); 51712382Sralph } 51812382Sralph } 51912382Sralph 52012382Sralph /* 52112382Sralph * Enable printing on the specified printer and startup the daemon. 52212382Sralph */ 52312382Sralph start(argc, argv) 52412382Sralph char *argv[]; 52512382Sralph { 52612382Sralph register int c, status; 52712382Sralph register char *cp1, *cp2; 52812382Sralph char prbuf[100]; 52912382Sralph 53012382Sralph if (argc == 1) { 53112382Sralph printf("Usage: start {all | printer ...}\n"); 53212382Sralph return; 53312382Sralph } 53412382Sralph gethostname(host, sizeof(host)); 53512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 53612382Sralph printer = prbuf; 53712382Sralph while (getprent(line) > 0) { 53812382Sralph cp1 = prbuf; 53912382Sralph cp2 = line; 54012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 54112382Sralph *cp1++ = c; 54212382Sralph *cp1 = '\0'; 54312382Sralph startpr(1); 54412382Sralph } 54512382Sralph return; 54612382Sralph } 54712382Sralph while (--argc) { 54812382Sralph printer = *++argv; 54912382Sralph if ((status = pgetent(line, printer)) < 0) { 55012514Sralph printf("cannot open printer description file\n"); 55112382Sralph continue; 55212382Sralph } else if (status == 0) { 55312514Sralph printf("unknown printer %s\n", printer); 55412382Sralph continue; 55512382Sralph } 55612382Sralph startpr(1); 55712382Sralph } 55812382Sralph } 55912382Sralph 56012382Sralph startpr(enable) 56112382Sralph { 56212382Sralph struct stat stbuf; 56312382Sralph 56412382Sralph bp = pbuf; 56512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 56612382Sralph SD = DEFSPOOL; 56712382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 56812382Sralph LO = DEFLOCK; 56912382Sralph (void) sprintf(line, "%s/%s", SD, LO); 57012382Sralph printf("%s:\n", printer); 57112382Sralph 57212382Sralph /* 57312382Sralph * Turn off the owner execute bit of the lock file to enable printing. 57412382Sralph */ 57512382Sralph if (enable && stat(line, &stbuf) >= 0) { 57612382Sralph if (chmod(line, stbuf.st_mode & 0677) < 0) 57712382Sralph printf("\tcannot enable printing\n"); 57812382Sralph else 57912382Sralph printf("\tprinting enabled\n"); 58012382Sralph } 58113727Sroot if (!startdaemon(printer)) 58212382Sralph printf("\tcouldn't start daemon\n"); 58312382Sralph else 58412382Sralph printf("\tdaemon started\n"); 58512382Sralph } 58612382Sralph 58712382Sralph /* 58812382Sralph * Print the status of each queue listed or all the queues. 58912382Sralph */ 59012382Sralph status(argc, argv) 59112382Sralph char *argv[]; 59212382Sralph { 59312382Sralph register int c, status; 59412382Sralph register char *cp1, *cp2; 59512382Sralph char prbuf[100]; 59612382Sralph 59712382Sralph if (argc == 1) { 59812382Sralph printer = prbuf; 59912382Sralph while (getprent(line) > 0) { 60012382Sralph cp1 = prbuf; 60112382Sralph cp2 = line; 60212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 60312382Sralph *cp1++ = c; 60412382Sralph *cp1 = '\0'; 60512382Sralph prstat(); 60612382Sralph } 60712382Sralph return; 60812382Sralph } 60912382Sralph while (--argc) { 61012382Sralph printer = *++argv; 61112382Sralph if ((status = pgetent(line, printer)) < 0) { 61212514Sralph printf("cannot open printer description file\n"); 61312382Sralph continue; 61412382Sralph } else if (status == 0) { 61512514Sralph printf("unknown printer %s\n", printer); 61612382Sralph continue; 61712382Sralph } 61812382Sralph prstat(); 61912382Sralph } 62012382Sralph } 62112382Sralph 62212382Sralph /* 62312382Sralph * Print the status of the printer queue. 62412382Sralph */ 62512382Sralph prstat() 62612382Sralph { 62712382Sralph struct stat stbuf; 62812382Sralph register int fd, i; 62912382Sralph register struct direct *dp; 63012382Sralph DIR *dirp; 63112382Sralph 63212382Sralph bp = pbuf; 63312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 63412382Sralph SD = DEFSPOOL; 63512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 63612382Sralph LO = DEFLOCK; 63712382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 63812382Sralph ST = DEFSTAT; 63912382Sralph printf("%s:\n", printer); 64012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 64112382Sralph if (stat(line, &stbuf) >= 0) { 64212382Sralph printf("\tqueuing is %s\n", 64312382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 64412382Sralph printf("\tprinting is %s\n", 64512382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 64612382Sralph } else { 64712382Sralph printf("\tqueuing is enabled\n"); 64812382Sralph printf("\tprinting is enabled\n"); 64912382Sralph } 65012382Sralph if ((dirp = opendir(SD)) == NULL) { 65112382Sralph printf("\tcannot examine spool directory\n"); 65212382Sralph return; 65312382Sralph } 65412382Sralph i = 0; 65512382Sralph while ((dp = readdir(dirp)) != NULL) { 65612382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 65712382Sralph i++; 65812382Sralph } 65912382Sralph closedir(dirp); 66012382Sralph if (i == 0) 66112382Sralph printf("\tno entries\n"); 66212382Sralph else if (i == 1) 66312382Sralph printf("\t1 entry in spool area\n"); 66412382Sralph else 66512382Sralph printf("\t%d entries in spool area\n", i); 66613146Ssam fd = open(line, O_RDONLY); 66713146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 66813168Sralph (void) close(fd); /* unlocks as well */ 66912382Sralph printf("\tno daemon present\n"); 67012382Sralph return; 67112382Sralph } 67212382Sralph (void) close(fd); 67312382Sralph putchar('\t'); 67412382Sralph (void) sprintf(line, "%s/%s", SD, ST); 67513146Ssam fd = open(line, O_RDONLY); 67613146Ssam if (fd >= 0) { 67713146Ssam (void) flock(fd, LOCK_SH); 67812382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 67912382Sralph (void) fwrite(line, 1, i, stdout); 68013168Sralph (void) close(fd); /* unlocks as well */ 68112382Sralph } 68212382Sralph } 68312382Sralph 68412382Sralph /* 68512382Sralph * Stop the specified daemon after completing the current job and disable 68612382Sralph * printing. 68712382Sralph */ 68812382Sralph stop(argc, argv) 68912382Sralph char *argv[]; 69012382Sralph { 69112382Sralph register int c, status; 69212382Sralph register char *cp1, *cp2; 69312382Sralph char prbuf[100]; 69412382Sralph 69512382Sralph if (argc == 1) { 69612382Sralph printf("Usage: stop {all | printer ...}\n"); 69712382Sralph return; 69812382Sralph } 69912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 70012382Sralph printer = prbuf; 70112382Sralph while (getprent(line) > 0) { 70212382Sralph cp1 = prbuf; 70312382Sralph cp2 = line; 70412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 70512382Sralph *cp1++ = c; 70612382Sralph *cp1 = '\0'; 70712382Sralph stoppr(); 70812382Sralph } 70912382Sralph return; 71012382Sralph } 71112382Sralph while (--argc) { 71212382Sralph printer = *++argv; 71312382Sralph if ((status = pgetent(line, printer)) < 0) { 71412514Sralph printf("cannot open printer description file\n"); 71512382Sralph continue; 71612382Sralph } else if (status == 0) { 71712514Sralph printf("unknown printer %s\n", printer); 71812382Sralph continue; 71912382Sralph } 72012382Sralph stoppr(); 72112382Sralph } 72212382Sralph } 72312382Sralph 72412382Sralph stoppr() 72512382Sralph { 72612382Sralph register int fd; 72712382Sralph struct stat stbuf; 72812382Sralph 72912382Sralph bp = pbuf; 73012382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 73112382Sralph SD = DEFSPOOL; 73212382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 73312382Sralph LO = DEFLOCK; 73412382Sralph (void) sprintf(line, "%s/%s", SD, LO); 73512382Sralph printf("%s:\n", printer); 73612382Sralph 73712382Sralph /* 73812382Sralph * Turn on the owner execute bit of the lock file to disable printing. 73912382Sralph */ 74012382Sralph if (stat(line, &stbuf) >= 0) { 74112382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 74212382Sralph printf("\tcannot disable printing\n"); 74312382Sralph else 74412382Sralph printf("\tprinting disabled\n"); 74512382Sralph } else if (errno == ENOENT) { 74613146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 74712382Sralph printf("\tcannot create lock file\n"); 74812382Sralph else { 74912382Sralph (void) close(fd); 75012382Sralph printf("\tprinting disabled\n"); 75112382Sralph } 75212382Sralph } else 75312382Sralph printf("\tcannot stat lock file\n"); 75412382Sralph } 75513727Sroot 75615719Sralph struct queue **queue; 75715719Sralph int nitems; 75815719Sralph time_t mtime; 75915719Sralph 76013727Sroot /* 76113727Sroot * Put the specified jobs at the top of printer queue. 76213727Sroot */ 76313727Sroot topq(argc, argv) 76413727Sroot char *argv[]; 76513727Sroot { 76615719Sralph register int n, i; 76713727Sroot struct stat stbuf; 76813727Sroot register char *cfname; 76915719Sralph int status, changed; 77013727Sroot 77115719Sralph if (argc < 3) { 77213727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 77313727Sroot return; 77413727Sroot } 77513727Sroot 77613727Sroot --argc; 77713727Sroot printer = *++argv; 77813727Sroot status = pgetent(line, printer); 77913727Sroot if (status < 0) { 78013727Sroot printf("cannot open printer description file\n"); 78113727Sroot return; 78214151Sralph } else if (status == 0) { 78313727Sroot printf("%s: unknown printer\n", printer); 78413727Sroot return; 78513727Sroot } 78613727Sroot bp = pbuf; 78713727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 78813727Sroot SD = DEFSPOOL; 78913727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 79013727Sroot LO = DEFLOCK; 79113727Sroot printf("%s:\n", printer); 79213727Sroot 79313727Sroot if (chdir(SD) < 0) { 79413727Sroot printf("\tcannot chdir to %s\n", SD); 79513727Sroot return; 79613727Sroot } 79713727Sroot nitems = getq(&queue); 79815719Sralph if (nitems == 0) 79915719Sralph return; 80015719Sralph changed = 0; 80115719Sralph mtime = queue[0]->q_time; 80215719Sralph for (i = argc; --i; ) { 80315719Sralph if (doarg(argv[i]) == 0) { 80415719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 80513727Sroot continue; 80615719Sralph } else 80714151Sralph changed++; 80813727Sroot } 80915719Sralph for (i = 0; i < nitems; i++) 81015719Sralph free(queue[i]); 81115719Sralph free(queue); 81215719Sralph if (!changed) { 81315719Sralph printf("\tqueue order unchanged\n"); 81415719Sralph return; 81513727Sroot } 81613727Sroot /* 81713727Sroot * Turn on the public execute bit of the lock file to 81813727Sroot * get lpd to rebuild the queue after the current job. 81913727Sroot */ 82014151Sralph if (changed && stat(LO, &stbuf) >= 0) 82114151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 82213727Sroot } 82313727Sroot 82415719Sralph /* 82515719Sralph * Reposition the job by changing the modification time of 82615719Sralph * the control file. 82713727Sroot */ 82815719Sralph touch(q) 82915719Sralph struct queue *q; 83013727Sroot { 83115719Sralph struct timeval tvp[2]; 83213727Sroot 83315719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 83415719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 83515719Sralph return(utimes(q->q_name, tvp)); 83613727Sroot } 83713727Sroot 83813727Sroot /* 83913727Sroot * Checks if specified job name is in the printer's queue. 84013727Sroot * Returns: negative (-1) if argument name is not in the queue. 84113727Sroot */ 84215719Sralph doarg(job) 84313727Sroot char *job; 84413727Sroot { 84515719Sralph register struct queue **qq; 84615719Sralph register int jobnum, n; 84715719Sralph register char *cp, *machine; 84815719Sralph int cnt = 0; 84914151Sralph FILE *fp; 85013727Sroot 85115719Sralph /* 85215719Sralph * Look for a job item consisting of system name, colon, number 85315719Sralph * (example: ucbarpa:114) 85415719Sralph */ 85515719Sralph if ((cp = index(job, ':')) != NULL) { 85615719Sralph machine = job; 85715719Sralph *cp++ = '\0'; 85815719Sralph job = cp; 85915719Sralph } else 86015719Sralph machine = NULL; 86115719Sralph 86215719Sralph /* 86315719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 86415719Sralph */ 86513727Sroot if (isdigit(*job)) { 86613727Sroot jobnum = 0; 86713727Sroot do 86813727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 86913727Sroot while (isdigit(*job)); 87015719Sralph for (qq = queue + nitems; --qq >= queue; ) { 87113727Sroot n = 0; 87215719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 87314151Sralph n = n * 10 + (*cp++ - '0'); 87415719Sralph if (jobnum != n) 87515719Sralph continue; 87615719Sralph if (*job && strcmp(job, cp) != 0) 87715719Sralph continue; 87815719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 87915719Sralph continue; 88015719Sralph if (touch(*qq) == 0) { 88115719Sralph printf("\tmoved %s\n", (*qq)->q_name); 88215719Sralph cnt++; 88315719Sralph } 88413727Sroot } 88515719Sralph return(cnt); 88615719Sralph } 88715719Sralph /* 88815719Sralph * Process item consisting of owner's name (example: henry). 88915719Sralph */ 89015719Sralph for (qq = queue + nitems; --qq >= queue; ) { 89115719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 89213727Sroot continue; 89315719Sralph while (getline(fp) > 0) 89415719Sralph if (line[0] == 'P') 89515719Sralph break; 89615719Sralph (void) fclose(fp); 89715719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 89815719Sralph continue; 89915719Sralph if (touch(*qq) == 0) { 90015719Sralph printf("\tmoved %s\n", (*qq)->q_name); 90115719Sralph cnt++; 90213727Sroot } 90313727Sroot } 90415719Sralph return(cnt); 90513727Sroot } 906