112382Sralph #ifndef lint 2*16204Sralph static char sccsid[] = "@(#)cmds.c 4.11 (Berkeley) 03/19/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 /* 37315907Sralph * Disable queuing and printing and put a message into the status file 37415907Sralph * (reason for being down). 37515907Sralph */ 37615907Sralph down(argc, argv) 37715907Sralph char *argv[]; 37815907Sralph { 37915907Sralph register int c, status; 38015907Sralph register char *cp1, *cp2; 38115907Sralph char prbuf[100]; 38215907Sralph 38315907Sralph if (argc == 1) { 384*16204Sralph printf("Usage: down {all | printer} [message ...]\n"); 38515907Sralph return; 38615907Sralph } 38715907Sralph if (!strcmp(argv[1], "all")) { 38815907Sralph printer = prbuf; 38915907Sralph while (getprent(line) > 0) { 39015907Sralph cp1 = prbuf; 39115907Sralph cp2 = line; 39215907Sralph while ((c = *cp2++) && c != '|' && c != ':') 39315907Sralph *cp1++ = c; 39415907Sralph *cp1 = '\0'; 39515907Sralph putmsg(argc - 2, argv + 2); 39615907Sralph } 39715907Sralph return; 39815907Sralph } 39915907Sralph printer = argv[1]; 40015907Sralph if ((status = pgetent(line, printer)) < 0) { 40115907Sralph printf("cannot open printer description file\n"); 40215907Sralph return; 40315907Sralph } else if (status == 0) { 40415907Sralph printf("unknown printer %s\n", printer); 40515907Sralph return; 40615907Sralph } 40715907Sralph putmsg(argc - 2, argv + 2); 40815907Sralph } 40915907Sralph 41015907Sralph putmsg(argc, argv) 41115907Sralph char **argv; 41215907Sralph { 41315907Sralph register int fd; 41415907Sralph register char *cp1, *cp2; 41515907Sralph char buf[1024]; 41615907Sralph struct stat stbuf; 41715907Sralph 41815907Sralph bp = pbuf; 41915907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 42015907Sralph SD = DEFSPOOL; 42115907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 42215907Sralph LO = DEFLOCK; 42315907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 42415907Sralph ST = DEFSTAT; 42515907Sralph printf("%s:\n", printer); 42615907Sralph /* 42715907Sralph * Turn on the group execute bit of the lock file to disable queuing and 42815907Sralph * turn on the owner execute bit of the lock file to disable printing. 42915907Sralph */ 43015907Sralph (void) sprintf(line, "%s/%s", SD, LO); 43115907Sralph if (stat(line, &stbuf) >= 0) { 43215907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 43315907Sralph printf("\tcannot disable queuing\n"); 43415907Sralph else 43515907Sralph printf("\tprinter and queuing disabled\n"); 43615907Sralph } else if (errno == ENOENT) { 43715907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 43815907Sralph printf("\tcannot create lock file\n"); 43915907Sralph else { 44015907Sralph (void) close(fd); 44115907Sralph printf("\tprinter and queuing disabled\n"); 44215907Sralph } 44315907Sralph return; 44415907Sralph } else 44515907Sralph printf("\tcannot stat lock file\n"); 44615907Sralph /* 44715907Sralph * Write the message into the status file. 44815907Sralph */ 44915907Sralph (void) sprintf(line, "%s/%s", SD, ST); 45015907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 45115907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 45215907Sralph printf("\tcannot create status file\n"); 45315907Sralph return; 45415907Sralph } 45515907Sralph (void) ftruncate(fd, 0); 456*16204Sralph if (argc <= 0) { 457*16204Sralph (void) write(fd, "\n", 1); 458*16204Sralph (void) close(fd); 459*16204Sralph return; 460*16204Sralph } 46115907Sralph cp1 = buf; 46215907Sralph while (--argc >= 0) { 46315907Sralph cp2 = *argv++; 46415907Sralph while (*cp1++ = *cp2++) 46515907Sralph ; 46615907Sralph cp1[-1] = ' '; 46715907Sralph } 46815907Sralph cp1[-1] = '\n'; 46915907Sralph *cp1 = '\0'; 47015907Sralph (void) write(fd, buf, strlen(buf)); 47115907Sralph (void) close(fd); 47215907Sralph } 47315907Sralph 47415907Sralph /* 47512382Sralph * Exit lpc 47612382Sralph */ 47712382Sralph quit(argc, argv) 47812382Sralph char *argv[]; 47912382Sralph { 48012382Sralph exit(0); 48112382Sralph } 48212382Sralph 48312382Sralph /* 48412382Sralph * Startup the daemon. 48512382Sralph */ 48612382Sralph restart(argc, argv) 48712382Sralph char *argv[]; 48812382Sralph { 48912382Sralph register int c, status; 49012382Sralph register char *cp1, *cp2; 49112382Sralph char prbuf[100]; 49212382Sralph 49312382Sralph if (argc == 1) { 49412382Sralph printf("Usage: restart {all | printer ...}\n"); 49512382Sralph return; 49612382Sralph } 49712382Sralph gethostname(host, sizeof(host)); 49812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 49912382Sralph printer = prbuf; 50012382Sralph while (getprent(line) > 0) { 50112382Sralph cp1 = prbuf; 50212382Sralph cp2 = line; 50312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 50412382Sralph *cp1++ = c; 50512382Sralph *cp1 = '\0'; 50612382Sralph startpr(0); 50712382Sralph } 50812382Sralph return; 50912382Sralph } 51012382Sralph while (--argc) { 51112382Sralph printer = *++argv; 51212382Sralph if ((status = pgetent(line, printer)) < 0) { 51312514Sralph printf("cannot open printer description file\n"); 51412382Sralph continue; 51512382Sralph } else if (status == 0) { 51612514Sralph printf("unknown printer %s\n", printer); 51712382Sralph continue; 51812382Sralph } 51912382Sralph startpr(0); 52012382Sralph } 52112382Sralph } 52212382Sralph 52312382Sralph /* 52412382Sralph * Enable printing on the specified printer and startup the daemon. 52512382Sralph */ 52612382Sralph start(argc, argv) 52712382Sralph char *argv[]; 52812382Sralph { 52912382Sralph register int c, status; 53012382Sralph register char *cp1, *cp2; 53112382Sralph char prbuf[100]; 53212382Sralph 53312382Sralph if (argc == 1) { 53412382Sralph printf("Usage: start {all | printer ...}\n"); 53512382Sralph return; 53612382Sralph } 53712382Sralph gethostname(host, sizeof(host)); 53812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 53912382Sralph printer = prbuf; 54012382Sralph while (getprent(line) > 0) { 54112382Sralph cp1 = prbuf; 54212382Sralph cp2 = line; 54312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 54412382Sralph *cp1++ = c; 54512382Sralph *cp1 = '\0'; 54612382Sralph startpr(1); 54712382Sralph } 54812382Sralph return; 54912382Sralph } 55012382Sralph while (--argc) { 55112382Sralph printer = *++argv; 55212382Sralph if ((status = pgetent(line, printer)) < 0) { 55312514Sralph printf("cannot open printer description file\n"); 55412382Sralph continue; 55512382Sralph } else if (status == 0) { 55612514Sralph printf("unknown printer %s\n", printer); 55712382Sralph continue; 55812382Sralph } 55912382Sralph startpr(1); 56012382Sralph } 56112382Sralph } 56212382Sralph 56312382Sralph startpr(enable) 56412382Sralph { 56512382Sralph struct stat stbuf; 56612382Sralph 56712382Sralph bp = pbuf; 56812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 56912382Sralph SD = DEFSPOOL; 57012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 57112382Sralph LO = DEFLOCK; 57212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 57312382Sralph printf("%s:\n", printer); 57412382Sralph 57512382Sralph /* 57612382Sralph * Turn off the owner execute bit of the lock file to enable printing. 57712382Sralph */ 57812382Sralph if (enable && stat(line, &stbuf) >= 0) { 57912382Sralph if (chmod(line, stbuf.st_mode & 0677) < 0) 58012382Sralph printf("\tcannot enable printing\n"); 58112382Sralph else 58212382Sralph printf("\tprinting enabled\n"); 58312382Sralph } 58413727Sroot if (!startdaemon(printer)) 58512382Sralph printf("\tcouldn't start daemon\n"); 58612382Sralph else 58712382Sralph printf("\tdaemon started\n"); 58812382Sralph } 58912382Sralph 59012382Sralph /* 59112382Sralph * Print the status of each queue listed or all the queues. 59212382Sralph */ 59312382Sralph status(argc, argv) 59412382Sralph char *argv[]; 59512382Sralph { 59612382Sralph register int c, status; 59712382Sralph register char *cp1, *cp2; 59812382Sralph char prbuf[100]; 59912382Sralph 60012382Sralph if (argc == 1) { 60112382Sralph printer = prbuf; 60212382Sralph while (getprent(line) > 0) { 60312382Sralph cp1 = prbuf; 60412382Sralph cp2 = line; 60512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 60612382Sralph *cp1++ = c; 60712382Sralph *cp1 = '\0'; 60812382Sralph prstat(); 60912382Sralph } 61012382Sralph return; 61112382Sralph } 61212382Sralph while (--argc) { 61312382Sralph printer = *++argv; 61412382Sralph if ((status = pgetent(line, printer)) < 0) { 61512514Sralph printf("cannot open printer description file\n"); 61612382Sralph continue; 61712382Sralph } else if (status == 0) { 61812514Sralph printf("unknown printer %s\n", printer); 61912382Sralph continue; 62012382Sralph } 62112382Sralph prstat(); 62212382Sralph } 62312382Sralph } 62412382Sralph 62512382Sralph /* 62612382Sralph * Print the status of the printer queue. 62712382Sralph */ 62812382Sralph prstat() 62912382Sralph { 63012382Sralph struct stat stbuf; 63112382Sralph register int fd, i; 63212382Sralph register struct direct *dp; 63312382Sralph DIR *dirp; 63412382Sralph 63512382Sralph bp = pbuf; 63612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 63712382Sralph SD = DEFSPOOL; 63812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 63912382Sralph LO = DEFLOCK; 64012382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 64112382Sralph ST = DEFSTAT; 64212382Sralph printf("%s:\n", printer); 64312382Sralph (void) sprintf(line, "%s/%s", SD, LO); 64412382Sralph if (stat(line, &stbuf) >= 0) { 64512382Sralph printf("\tqueuing is %s\n", 64612382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 64712382Sralph printf("\tprinting is %s\n", 64812382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 64912382Sralph } else { 65012382Sralph printf("\tqueuing is enabled\n"); 65112382Sralph printf("\tprinting is enabled\n"); 65212382Sralph } 65312382Sralph if ((dirp = opendir(SD)) == NULL) { 65412382Sralph printf("\tcannot examine spool directory\n"); 65512382Sralph return; 65612382Sralph } 65712382Sralph i = 0; 65812382Sralph while ((dp = readdir(dirp)) != NULL) { 65912382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 66012382Sralph i++; 66112382Sralph } 66212382Sralph closedir(dirp); 66312382Sralph if (i == 0) 66412382Sralph printf("\tno entries\n"); 66512382Sralph else if (i == 1) 66612382Sralph printf("\t1 entry in spool area\n"); 66712382Sralph else 66812382Sralph printf("\t%d entries in spool area\n", i); 66913146Ssam fd = open(line, O_RDONLY); 67013146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 67113168Sralph (void) close(fd); /* unlocks as well */ 67212382Sralph printf("\tno daemon present\n"); 67312382Sralph return; 67412382Sralph } 67512382Sralph (void) close(fd); 67612382Sralph putchar('\t'); 67712382Sralph (void) sprintf(line, "%s/%s", SD, ST); 67813146Ssam fd = open(line, O_RDONLY); 67913146Ssam if (fd >= 0) { 68013146Ssam (void) flock(fd, LOCK_SH); 68112382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 68212382Sralph (void) fwrite(line, 1, i, stdout); 68313168Sralph (void) close(fd); /* unlocks as well */ 68412382Sralph } 68512382Sralph } 68612382Sralph 68712382Sralph /* 68812382Sralph * Stop the specified daemon after completing the current job and disable 68912382Sralph * printing. 69012382Sralph */ 69112382Sralph stop(argc, argv) 69212382Sralph char *argv[]; 69312382Sralph { 69412382Sralph register int c, status; 69512382Sralph register char *cp1, *cp2; 69612382Sralph char prbuf[100]; 69712382Sralph 69812382Sralph if (argc == 1) { 69912382Sralph printf("Usage: stop {all | printer ...}\n"); 70012382Sralph return; 70112382Sralph } 70212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 70312382Sralph printer = prbuf; 70412382Sralph while (getprent(line) > 0) { 70512382Sralph cp1 = prbuf; 70612382Sralph cp2 = line; 70712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 70812382Sralph *cp1++ = c; 70912382Sralph *cp1 = '\0'; 71012382Sralph stoppr(); 71112382Sralph } 71212382Sralph return; 71312382Sralph } 71412382Sralph while (--argc) { 71512382Sralph printer = *++argv; 71612382Sralph if ((status = pgetent(line, printer)) < 0) { 71712514Sralph printf("cannot open printer description file\n"); 71812382Sralph continue; 71912382Sralph } else if (status == 0) { 72012514Sralph printf("unknown printer %s\n", printer); 72112382Sralph continue; 72212382Sralph } 72312382Sralph stoppr(); 72412382Sralph } 72512382Sralph } 72612382Sralph 72712382Sralph stoppr() 72812382Sralph { 72912382Sralph register int fd; 73012382Sralph struct stat stbuf; 73112382Sralph 73212382Sralph bp = pbuf; 73312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 73412382Sralph SD = DEFSPOOL; 73512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 73612382Sralph LO = DEFLOCK; 73712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 73812382Sralph printf("%s:\n", printer); 73912382Sralph 74012382Sralph /* 74112382Sralph * Turn on the owner execute bit of the lock file to disable printing. 74212382Sralph */ 74312382Sralph if (stat(line, &stbuf) >= 0) { 74412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 74512382Sralph printf("\tcannot disable printing\n"); 74612382Sralph else 74712382Sralph printf("\tprinting disabled\n"); 74812382Sralph } else if (errno == ENOENT) { 74913146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 75012382Sralph printf("\tcannot create lock file\n"); 75112382Sralph else { 75212382Sralph (void) close(fd); 75312382Sralph printf("\tprinting disabled\n"); 75412382Sralph } 75512382Sralph } else 75612382Sralph printf("\tcannot stat lock file\n"); 75712382Sralph } 75813727Sroot 75915719Sralph struct queue **queue; 76015719Sralph int nitems; 76115719Sralph time_t mtime; 76215719Sralph 76313727Sroot /* 76413727Sroot * Put the specified jobs at the top of printer queue. 76513727Sroot */ 76613727Sroot topq(argc, argv) 76713727Sroot char *argv[]; 76813727Sroot { 76915719Sralph register int n, i; 77013727Sroot struct stat stbuf; 77113727Sroot register char *cfname; 77215719Sralph int status, changed; 77313727Sroot 77415719Sralph if (argc < 3) { 77513727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 77613727Sroot return; 77713727Sroot } 77813727Sroot 77913727Sroot --argc; 78013727Sroot printer = *++argv; 78113727Sroot status = pgetent(line, printer); 78213727Sroot if (status < 0) { 78313727Sroot printf("cannot open printer description file\n"); 78413727Sroot return; 78514151Sralph } else if (status == 0) { 78613727Sroot printf("%s: unknown printer\n", printer); 78713727Sroot return; 78813727Sroot } 78913727Sroot bp = pbuf; 79013727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 79113727Sroot SD = DEFSPOOL; 79213727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 79313727Sroot LO = DEFLOCK; 79413727Sroot printf("%s:\n", printer); 79513727Sroot 79613727Sroot if (chdir(SD) < 0) { 79713727Sroot printf("\tcannot chdir to %s\n", SD); 79813727Sroot return; 79913727Sroot } 80013727Sroot nitems = getq(&queue); 80115719Sralph if (nitems == 0) 80215719Sralph return; 80315719Sralph changed = 0; 80415719Sralph mtime = queue[0]->q_time; 80515719Sralph for (i = argc; --i; ) { 80615719Sralph if (doarg(argv[i]) == 0) { 80715719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 80813727Sroot continue; 80915719Sralph } else 81014151Sralph changed++; 81113727Sroot } 81215719Sralph for (i = 0; i < nitems; i++) 81315719Sralph free(queue[i]); 81415719Sralph free(queue); 81515719Sralph if (!changed) { 81615719Sralph printf("\tqueue order unchanged\n"); 81715719Sralph return; 81813727Sroot } 81913727Sroot /* 82013727Sroot * Turn on the public execute bit of the lock file to 82113727Sroot * get lpd to rebuild the queue after the current job. 82213727Sroot */ 82314151Sralph if (changed && stat(LO, &stbuf) >= 0) 82414151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 82513727Sroot } 82613727Sroot 82715719Sralph /* 82815719Sralph * Reposition the job by changing the modification time of 82915719Sralph * the control file. 83013727Sroot */ 83115719Sralph touch(q) 83215719Sralph struct queue *q; 83313727Sroot { 83415719Sralph struct timeval tvp[2]; 83513727Sroot 83615719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 83715719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 83815719Sralph return(utimes(q->q_name, tvp)); 83913727Sroot } 84013727Sroot 84113727Sroot /* 84213727Sroot * Checks if specified job name is in the printer's queue. 84313727Sroot * Returns: negative (-1) if argument name is not in the queue. 84413727Sroot */ 84515719Sralph doarg(job) 84613727Sroot char *job; 84713727Sroot { 84815719Sralph register struct queue **qq; 84915719Sralph register int jobnum, n; 85015719Sralph register char *cp, *machine; 85115719Sralph int cnt = 0; 85214151Sralph FILE *fp; 85313727Sroot 85415719Sralph /* 85515719Sralph * Look for a job item consisting of system name, colon, number 85615719Sralph * (example: ucbarpa:114) 85715719Sralph */ 85815719Sralph if ((cp = index(job, ':')) != NULL) { 85915719Sralph machine = job; 86015719Sralph *cp++ = '\0'; 86115719Sralph job = cp; 86215719Sralph } else 86315719Sralph machine = NULL; 86415719Sralph 86515719Sralph /* 86615719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 86715719Sralph */ 86813727Sroot if (isdigit(*job)) { 86913727Sroot jobnum = 0; 87013727Sroot do 87113727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 87213727Sroot while (isdigit(*job)); 87315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 87413727Sroot n = 0; 87515719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 87614151Sralph n = n * 10 + (*cp++ - '0'); 87715719Sralph if (jobnum != n) 87815719Sralph continue; 87915719Sralph if (*job && strcmp(job, cp) != 0) 88015719Sralph continue; 88115719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 88215719Sralph continue; 88315719Sralph if (touch(*qq) == 0) { 88415719Sralph printf("\tmoved %s\n", (*qq)->q_name); 88515719Sralph cnt++; 88615719Sralph } 88713727Sroot } 88815719Sralph return(cnt); 88915719Sralph } 89015719Sralph /* 89115719Sralph * Process item consisting of owner's name (example: henry). 89215719Sralph */ 89315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 89415719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 89513727Sroot continue; 89615719Sralph while (getline(fp) > 0) 89715719Sralph if (line[0] == 'P') 89815719Sralph break; 89915719Sralph (void) fclose(fp); 90015719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 90115719Sralph continue; 90215719Sralph if (touch(*qq) == 0) { 90315719Sralph printf("\tmoved %s\n", (*qq)->q_name); 90415719Sralph cnt++; 90513727Sroot } 90613727Sroot } 90715719Sralph return(cnt); 90813727Sroot } 909