112382Sralph #ifndef lint 2*16755Sralph static char sccsid[] = "@(#)cmds.c 4.12 (Berkeley) 07/24/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'; 34*16755Sralph abortpr(1); 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 } 47*16755Sralph abortpr(1); 4812382Sralph } 4912382Sralph } 5012382Sralph 51*16755Sralph abortpr(dis) 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 */ 68*16755Sralph if (dis) { 69*16755Sralph if (stat(line, &stbuf) >= 0) { 70*16755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 71*16755Sralph printf("\tcannot disable printing\n"); 72*16755Sralph else 73*16755Sralph printf("\tprinting disabled\n"); 74*16755Sralph } else if (errno == ENOENT) { 75*16755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 76*16755Sralph printf("\tcannot create lock file\n"); 77*16755Sralph else { 78*16755Sralph (void) close(fd); 79*16755Sralph printf("\tprinting disabled\n"); 80*16755Sralph printf("\tno daemon to abort\n"); 81*16755Sralph } 82*16755Sralph return; 83*16755Sralph } else { 84*16755Sralph printf("\tcannot stat lock file\n"); 85*16755Sralph return; 8612382Sralph } 8712382Sralph } 8812382Sralph /* 8912382Sralph * Kill the current daemon to stop printing now. 9012382Sralph */ 9112382Sralph if ((fp = fopen(line, "r")) == NULL) { 9212382Sralph printf("\tcannot open lock file\n"); 9312382Sralph return; 9412382Sralph } 9513146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 9613168Sralph (void) fclose(fp); /* unlocks as well */ 9712382Sralph printf("\tno daemon to abort\n"); 9812382Sralph return; 9912382Sralph } 10012382Sralph (void) fclose(fp); 101*16755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 10212382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 10312382Sralph else 10412382Sralph printf("\tdaemon (pid %d) killed\n", pid); 10512382Sralph } 10612382Sralph 10712382Sralph /* 10812382Sralph * Remove all spool files and temporaries from the spooling area. 10912382Sralph */ 11012382Sralph clean(argc, argv) 11112382Sralph char *argv[]; 11212382Sralph { 11312382Sralph register int c, status; 11412382Sralph register char *cp1, *cp2; 11512382Sralph char prbuf[100]; 11612382Sralph 11712382Sralph if (argc == 1) { 11812382Sralph printf("Usage: clean {all | printer ...}\n"); 11912382Sralph return; 12012382Sralph } 12112382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 12212382Sralph printer = prbuf; 12312382Sralph while (getprent(line) > 0) { 12412382Sralph cp1 = prbuf; 12512382Sralph cp2 = line; 12612382Sralph while ((c = *cp2++) && c != '|' && c != ':') 12712382Sralph *cp1++ = c; 12812382Sralph *cp1 = '\0'; 12912382Sralph cleanpr(); 13012382Sralph } 13112382Sralph return; 13212382Sralph } 13312382Sralph while (--argc) { 13412382Sralph printer = *++argv; 13512382Sralph if ((status = pgetent(line, printer)) < 0) { 13612514Sralph printf("cannot open printer description file\n"); 13712382Sralph continue; 13812382Sralph } else if (status == 0) { 13912514Sralph printf("unknown printer %s\n", printer); 14012382Sralph continue; 14112382Sralph } 14212382Sralph cleanpr(); 14312382Sralph } 14412382Sralph } 14512382Sralph 14615719Sralph select(d) 14715719Sralph struct direct *d; 14815719Sralph { 14915719Sralph int c = d->d_name[0]; 15015719Sralph 15115719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 15215719Sralph return(1); 15315719Sralph return(0); 15415719Sralph } 15515719Sralph 15615719Sralph /* 15715719Sralph * Comparison routine for scandir. Sort by job number and machine, then 15815719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 15915719Sralph */ 16015719Sralph sortq(d1, d2) 16115719Sralph struct direct **d1, **d2; 16215719Sralph { 16315719Sralph int c1, c2; 16415719Sralph 16515719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 16615719Sralph return(c1); 16715719Sralph c1 = (*d1)->d_name[0]; 16815719Sralph c2 = (*d2)->d_name[0]; 16915719Sralph if (c1 == c2) 17015719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 17115719Sralph if (c1 == 'c') 17215719Sralph return(-1); 17315719Sralph if (c1 == 'd' || c2 == 'c') 17415719Sralph return(1); 17515719Sralph return(-1); 17615719Sralph } 17715719Sralph 17815719Sralph /* 17915719Sralph * Remove incomplete jobs from spooling area. 18015719Sralph */ 18112382Sralph cleanpr() 18212382Sralph { 18315719Sralph register int i, n; 18415719Sralph register char *cp, *cp1, *lp; 18515719Sralph struct direct **queue; 18615719Sralph int nitems; 18712382Sralph 18812382Sralph bp = pbuf; 18912382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 19012382Sralph SD = DEFSPOOL; 19112382Sralph printf("%s:\n", printer); 19212382Sralph 19315719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 19415719Sralph ; 19515719Sralph lp[-1] = '/'; 19615719Sralph 19715719Sralph nitems = scandir(SD, &queue, select, sortq); 19815719Sralph if (nitems < 0) { 19912382Sralph printf("\tcannot examine spool directory\n"); 20012382Sralph return; 20112382Sralph } 20215719Sralph if (nitems == 0) 20315719Sralph return; 20415719Sralph i = 0; 20515719Sralph do { 20615719Sralph cp = queue[i]->d_name; 20715719Sralph if (*cp == 'c') { 20815719Sralph n = 0; 20915719Sralph while (i + 1 < nitems) { 21015719Sralph cp1 = queue[i + 1]->d_name; 21115719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 21215719Sralph break; 21315719Sralph i++; 21415719Sralph n++; 21515719Sralph } 21615719Sralph if (n == 0) { 21715719Sralph strcpy(lp, cp); 21815719Sralph unlinkf(line); 21915719Sralph } 22015719Sralph } else { 22115719Sralph /* 22215719Sralph * Must be a df with no cf (otherwise, it would have 22315719Sralph * been skipped above) or a tf file (which can always 22415719Sralph * be removed). 22515719Sralph */ 22615719Sralph strcpy(lp, cp); 22715719Sralph unlinkf(line); 22812382Sralph } 22915719Sralph } while (++i < nitems); 23012382Sralph } 23115719Sralph 23215719Sralph unlinkf(name) 23315719Sralph char *name; 23415719Sralph { 23515719Sralph if (unlink(name) < 0) 23615719Sralph printf("\tcannot remove %s\n", name); 23715719Sralph else 23815719Sralph printf("\tremoved %s\n", name); 23915719Sralph } 24012382Sralph 24112382Sralph /* 24212382Sralph * Enable queuing to the printer (allow lpr's). 24312382Sralph */ 24412382Sralph enable(argc, argv) 24512382Sralph char *argv[]; 24612382Sralph { 24712382Sralph register int c, status; 24812382Sralph register char *cp1, *cp2; 24912382Sralph char prbuf[100]; 25012382Sralph 25112382Sralph if (argc == 1) { 25212382Sralph printf("Usage: enable {all | printer ...}\n"); 25312382Sralph return; 25412382Sralph } 25512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 25612382Sralph printer = prbuf; 25712382Sralph while (getprent(line) > 0) { 25812382Sralph cp1 = prbuf; 25912382Sralph cp2 = line; 26012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 26112382Sralph *cp1++ = c; 26212382Sralph *cp1 = '\0'; 26312382Sralph enablepr(); 26412382Sralph } 26512382Sralph return; 26612382Sralph } 26712382Sralph while (--argc) { 26812382Sralph printer = *++argv; 26912382Sralph if ((status = pgetent(line, printer)) < 0) { 27012514Sralph printf("cannot open printer description file\n"); 27112382Sralph continue; 27212382Sralph } else if (status == 0) { 27312514Sralph printf("unknown printer %s\n", printer); 27412382Sralph continue; 27512382Sralph } 27612382Sralph enablepr(); 27712382Sralph } 27812382Sralph } 27912382Sralph 28012382Sralph enablepr() 28112382Sralph { 28212382Sralph struct stat stbuf; 28312382Sralph 28412382Sralph bp = pbuf; 28512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 28612382Sralph SD = DEFSPOOL; 28712382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 28812382Sralph LO = DEFLOCK; 28912382Sralph (void) sprintf(line, "%s/%s", SD, LO); 29012382Sralph printf("%s:\n", printer); 29112382Sralph 29212382Sralph /* 29312382Sralph * Turn off the group execute bit of the lock file to enable queuing. 29412382Sralph */ 29512382Sralph if (stat(line, &stbuf) >= 0) { 29612382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 29712514Sralph printf("\tcannot enable queuing\n"); 29812382Sralph else 29912382Sralph printf("\tqueuing enabled\n"); 30012382Sralph } 30112382Sralph } 30212382Sralph 30312382Sralph /* 30412382Sralph * Disable queuing. 30512382Sralph */ 30612382Sralph disable(argc, argv) 30712382Sralph char *argv[]; 30812382Sralph { 30912382Sralph register int c, status; 31012382Sralph register char *cp1, *cp2; 31112382Sralph char prbuf[100]; 31212382Sralph 31312382Sralph if (argc == 1) { 31412382Sralph printf("Usage: disable {all | printer ...}\n"); 31512382Sralph return; 31612382Sralph } 31712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 31812382Sralph printer = prbuf; 31912382Sralph while (getprent(line) > 0) { 32012382Sralph cp1 = prbuf; 32112382Sralph cp2 = line; 32212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 32312382Sralph *cp1++ = c; 32412382Sralph *cp1 = '\0'; 32512382Sralph disablepr(); 32612382Sralph } 32712382Sralph return; 32812382Sralph } 32912382Sralph while (--argc) { 33012382Sralph printer = *++argv; 33112382Sralph if ((status = pgetent(line, printer)) < 0) { 33212514Sralph printf("cannot open printer description file\n"); 33312382Sralph continue; 33412382Sralph } else if (status == 0) { 33512514Sralph printf("unknown printer %s\n", printer); 33612382Sralph continue; 33712382Sralph } 33812382Sralph disablepr(); 33912382Sralph } 34012382Sralph } 34112382Sralph 34212382Sralph disablepr() 34312382Sralph { 34412382Sralph register int fd; 34512382Sralph struct stat stbuf; 34612382Sralph 34712382Sralph bp = pbuf; 34812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 34912382Sralph SD = DEFSPOOL; 35012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 35112382Sralph LO = DEFLOCK; 35212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 35312382Sralph printf("%s:\n", printer); 35412382Sralph /* 35512382Sralph * Turn on the group execute bit of the lock file to disable queuing. 35612382Sralph */ 35712382Sralph if (stat(line, &stbuf) >= 0) { 35812382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 35912382Sralph printf("\tcannot disable queuing\n"); 36012382Sralph else 36112382Sralph printf("\tqueuing disabled\n"); 36212382Sralph } else if (errno == ENOENT) { 36313146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 36412382Sralph printf("\tcannot create lock file\n"); 36512382Sralph else { 36612382Sralph (void) close(fd); 36712382Sralph printf("\tqueuing disabled\n"); 36812382Sralph } 36912382Sralph return; 37012382Sralph } else 37112382Sralph printf("\tcannot stat lock file\n"); 37212382Sralph } 37312382Sralph 37412382Sralph /* 37515907Sralph * Disable queuing and printing and put a message into the status file 37615907Sralph * (reason for being down). 37715907Sralph */ 37815907Sralph down(argc, argv) 37915907Sralph char *argv[]; 38015907Sralph { 38115907Sralph register int c, status; 38215907Sralph register char *cp1, *cp2; 38315907Sralph char prbuf[100]; 38415907Sralph 38515907Sralph if (argc == 1) { 38616204Sralph printf("Usage: down {all | printer} [message ...]\n"); 38715907Sralph return; 38815907Sralph } 38915907Sralph if (!strcmp(argv[1], "all")) { 39015907Sralph printer = prbuf; 39115907Sralph while (getprent(line) > 0) { 39215907Sralph cp1 = prbuf; 39315907Sralph cp2 = line; 39415907Sralph while ((c = *cp2++) && c != '|' && c != ':') 39515907Sralph *cp1++ = c; 39615907Sralph *cp1 = '\0'; 39715907Sralph putmsg(argc - 2, argv + 2); 39815907Sralph } 39915907Sralph return; 40015907Sralph } 40115907Sralph printer = argv[1]; 40215907Sralph if ((status = pgetent(line, printer)) < 0) { 40315907Sralph printf("cannot open printer description file\n"); 40415907Sralph return; 40515907Sralph } else if (status == 0) { 40615907Sralph printf("unknown printer %s\n", printer); 40715907Sralph return; 40815907Sralph } 40915907Sralph putmsg(argc - 2, argv + 2); 41015907Sralph } 41115907Sralph 41215907Sralph putmsg(argc, argv) 41315907Sralph char **argv; 41415907Sralph { 41515907Sralph register int fd; 41615907Sralph register char *cp1, *cp2; 41715907Sralph char buf[1024]; 41815907Sralph struct stat stbuf; 41915907Sralph 42015907Sralph bp = pbuf; 42115907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 42215907Sralph SD = DEFSPOOL; 42315907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 42415907Sralph LO = DEFLOCK; 42515907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 42615907Sralph ST = DEFSTAT; 42715907Sralph printf("%s:\n", printer); 42815907Sralph /* 42915907Sralph * Turn on the group execute bit of the lock file to disable queuing and 43015907Sralph * turn on the owner execute bit of the lock file to disable printing. 43115907Sralph */ 43215907Sralph (void) sprintf(line, "%s/%s", SD, LO); 43315907Sralph if (stat(line, &stbuf) >= 0) { 43415907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 43515907Sralph printf("\tcannot disable queuing\n"); 43615907Sralph else 43715907Sralph printf("\tprinter and queuing disabled\n"); 43815907Sralph } else if (errno == ENOENT) { 43915907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 44015907Sralph printf("\tcannot create lock file\n"); 44115907Sralph else { 44215907Sralph (void) close(fd); 44315907Sralph printf("\tprinter and queuing disabled\n"); 44415907Sralph } 44515907Sralph return; 44615907Sralph } else 44715907Sralph printf("\tcannot stat lock file\n"); 44815907Sralph /* 44915907Sralph * Write the message into the status file. 45015907Sralph */ 45115907Sralph (void) sprintf(line, "%s/%s", SD, ST); 45215907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 45315907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 45415907Sralph printf("\tcannot create status file\n"); 45515907Sralph return; 45615907Sralph } 45715907Sralph (void) ftruncate(fd, 0); 45816204Sralph if (argc <= 0) { 45916204Sralph (void) write(fd, "\n", 1); 46016204Sralph (void) close(fd); 46116204Sralph return; 46216204Sralph } 46315907Sralph cp1 = buf; 46415907Sralph while (--argc >= 0) { 46515907Sralph cp2 = *argv++; 46615907Sralph while (*cp1++ = *cp2++) 46715907Sralph ; 46815907Sralph cp1[-1] = ' '; 46915907Sralph } 47015907Sralph cp1[-1] = '\n'; 47115907Sralph *cp1 = '\0'; 47215907Sralph (void) write(fd, buf, strlen(buf)); 47315907Sralph (void) close(fd); 47415907Sralph } 47515907Sralph 47615907Sralph /* 47712382Sralph * Exit lpc 47812382Sralph */ 47912382Sralph quit(argc, argv) 48012382Sralph char *argv[]; 48112382Sralph { 48212382Sralph exit(0); 48312382Sralph } 48412382Sralph 48512382Sralph /* 486*16755Sralph * Kill and restart the daemon. 48712382Sralph */ 48812382Sralph restart(argc, argv) 48912382Sralph char *argv[]; 49012382Sralph { 49112382Sralph register int c, status; 49212382Sralph register char *cp1, *cp2; 49312382Sralph char prbuf[100]; 49412382Sralph 49512382Sralph if (argc == 1) { 49612382Sralph printf("Usage: restart {all | printer ...}\n"); 49712382Sralph return; 49812382Sralph } 49912382Sralph gethostname(host, sizeof(host)); 50012382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 50112382Sralph printer = prbuf; 50212382Sralph while (getprent(line) > 0) { 50312382Sralph cp1 = prbuf; 50412382Sralph cp2 = line; 50512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 50612382Sralph *cp1++ = c; 50712382Sralph *cp1 = '\0'; 508*16755Sralph abortpr(0); 50912382Sralph startpr(0); 51012382Sralph } 51112382Sralph return; 51212382Sralph } 51312382Sralph while (--argc) { 51412382Sralph printer = *++argv; 51512382Sralph if ((status = pgetent(line, printer)) < 0) { 51612514Sralph printf("cannot open printer description file\n"); 51712382Sralph continue; 51812382Sralph } else if (status == 0) { 51912514Sralph printf("unknown printer %s\n", printer); 52012382Sralph continue; 52112382Sralph } 522*16755Sralph abortpr(0); 52312382Sralph startpr(0); 52412382Sralph } 52512382Sralph } 52612382Sralph 52712382Sralph /* 52812382Sralph * Enable printing on the specified printer and startup the daemon. 52912382Sralph */ 53012382Sralph start(argc, argv) 53112382Sralph char *argv[]; 53212382Sralph { 53312382Sralph register int c, status; 53412382Sralph register char *cp1, *cp2; 53512382Sralph char prbuf[100]; 53612382Sralph 53712382Sralph if (argc == 1) { 53812382Sralph printf("Usage: start {all | printer ...}\n"); 53912382Sralph return; 54012382Sralph } 54112382Sralph gethostname(host, sizeof(host)); 54212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 54312382Sralph printer = prbuf; 54412382Sralph while (getprent(line) > 0) { 54512382Sralph cp1 = prbuf; 54612382Sralph cp2 = line; 54712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 54812382Sralph *cp1++ = c; 54912382Sralph *cp1 = '\0'; 55012382Sralph startpr(1); 55112382Sralph } 55212382Sralph return; 55312382Sralph } 55412382Sralph while (--argc) { 55512382Sralph printer = *++argv; 55612382Sralph if ((status = pgetent(line, printer)) < 0) { 55712514Sralph printf("cannot open printer description file\n"); 55812382Sralph continue; 55912382Sralph } else if (status == 0) { 56012514Sralph printf("unknown printer %s\n", printer); 56112382Sralph continue; 56212382Sralph } 56312382Sralph startpr(1); 56412382Sralph } 56512382Sralph } 56612382Sralph 56712382Sralph startpr(enable) 56812382Sralph { 56912382Sralph struct stat stbuf; 57012382Sralph 57112382Sralph bp = pbuf; 57212382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 57312382Sralph SD = DEFSPOOL; 57412382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 57512382Sralph LO = DEFLOCK; 57612382Sralph (void) sprintf(line, "%s/%s", SD, LO); 57712382Sralph printf("%s:\n", printer); 57812382Sralph 57912382Sralph /* 58012382Sralph * Turn off the owner execute bit of the lock file to enable printing. 58112382Sralph */ 58212382Sralph if (enable && stat(line, &stbuf) >= 0) { 583*16755Sralph if (chmod(line, stbuf.st_mode & (enable == 2)?0666:0677) < 0) 58412382Sralph printf("\tcannot enable printing\n"); 58512382Sralph else 58612382Sralph printf("\tprinting enabled\n"); 58712382Sralph } 58813727Sroot if (!startdaemon(printer)) 58912382Sralph printf("\tcouldn't start daemon\n"); 59012382Sralph else 59112382Sralph printf("\tdaemon started\n"); 59212382Sralph } 59312382Sralph 59412382Sralph /* 59512382Sralph * Print the status of each queue listed or all the queues. 59612382Sralph */ 59712382Sralph status(argc, argv) 59812382Sralph char *argv[]; 59912382Sralph { 60012382Sralph register int c, status; 60112382Sralph register char *cp1, *cp2; 60212382Sralph char prbuf[100]; 60312382Sralph 60412382Sralph if (argc == 1) { 60512382Sralph printer = prbuf; 60612382Sralph while (getprent(line) > 0) { 60712382Sralph cp1 = prbuf; 60812382Sralph cp2 = line; 60912382Sralph while ((c = *cp2++) && c != '|' && c != ':') 61012382Sralph *cp1++ = c; 61112382Sralph *cp1 = '\0'; 61212382Sralph prstat(); 61312382Sralph } 61412382Sralph return; 61512382Sralph } 61612382Sralph while (--argc) { 61712382Sralph printer = *++argv; 61812382Sralph if ((status = pgetent(line, printer)) < 0) { 61912514Sralph printf("cannot open printer description file\n"); 62012382Sralph continue; 62112382Sralph } else if (status == 0) { 62212514Sralph printf("unknown printer %s\n", printer); 62312382Sralph continue; 62412382Sralph } 62512382Sralph prstat(); 62612382Sralph } 62712382Sralph } 62812382Sralph 62912382Sralph /* 63012382Sralph * Print the status of the printer queue. 63112382Sralph */ 63212382Sralph prstat() 63312382Sralph { 63412382Sralph struct stat stbuf; 63512382Sralph register int fd, i; 63612382Sralph register struct direct *dp; 63712382Sralph DIR *dirp; 63812382Sralph 63912382Sralph bp = pbuf; 64012382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 64112382Sralph SD = DEFSPOOL; 64212382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 64312382Sralph LO = DEFLOCK; 64412382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 64512382Sralph ST = DEFSTAT; 64612382Sralph printf("%s:\n", printer); 64712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 64812382Sralph if (stat(line, &stbuf) >= 0) { 64912382Sralph printf("\tqueuing is %s\n", 65012382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 65112382Sralph printf("\tprinting is %s\n", 65212382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 65312382Sralph } else { 65412382Sralph printf("\tqueuing is enabled\n"); 65512382Sralph printf("\tprinting is enabled\n"); 65612382Sralph } 65712382Sralph if ((dirp = opendir(SD)) == NULL) { 65812382Sralph printf("\tcannot examine spool directory\n"); 65912382Sralph return; 66012382Sralph } 66112382Sralph i = 0; 66212382Sralph while ((dp = readdir(dirp)) != NULL) { 66312382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 66412382Sralph i++; 66512382Sralph } 66612382Sralph closedir(dirp); 66712382Sralph if (i == 0) 66812382Sralph printf("\tno entries\n"); 66912382Sralph else if (i == 1) 67012382Sralph printf("\t1 entry in spool area\n"); 67112382Sralph else 67212382Sralph printf("\t%d entries in spool area\n", i); 67313146Ssam fd = open(line, O_RDONLY); 67413146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 67513168Sralph (void) close(fd); /* unlocks as well */ 67612382Sralph printf("\tno daemon present\n"); 67712382Sralph return; 67812382Sralph } 67912382Sralph (void) close(fd); 68012382Sralph putchar('\t'); 68112382Sralph (void) sprintf(line, "%s/%s", SD, ST); 68213146Ssam fd = open(line, O_RDONLY); 68313146Ssam if (fd >= 0) { 68413146Ssam (void) flock(fd, LOCK_SH); 68512382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 68612382Sralph (void) fwrite(line, 1, i, stdout); 68713168Sralph (void) close(fd); /* unlocks as well */ 68812382Sralph } 68912382Sralph } 69012382Sralph 69112382Sralph /* 69212382Sralph * Stop the specified daemon after completing the current job and disable 69312382Sralph * printing. 69412382Sralph */ 69512382Sralph stop(argc, argv) 69612382Sralph char *argv[]; 69712382Sralph { 69812382Sralph register int c, status; 69912382Sralph register char *cp1, *cp2; 70012382Sralph char prbuf[100]; 70112382Sralph 70212382Sralph if (argc == 1) { 70312382Sralph printf("Usage: stop {all | printer ...}\n"); 70412382Sralph return; 70512382Sralph } 70612382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 70712382Sralph printer = prbuf; 70812382Sralph while (getprent(line) > 0) { 70912382Sralph cp1 = prbuf; 71012382Sralph cp2 = line; 71112382Sralph while ((c = *cp2++) && c != '|' && c != ':') 71212382Sralph *cp1++ = c; 71312382Sralph *cp1 = '\0'; 71412382Sralph stoppr(); 71512382Sralph } 71612382Sralph return; 71712382Sralph } 71812382Sralph while (--argc) { 71912382Sralph printer = *++argv; 72012382Sralph if ((status = pgetent(line, printer)) < 0) { 72112514Sralph printf("cannot open printer description file\n"); 72212382Sralph continue; 72312382Sralph } else if (status == 0) { 72412514Sralph printf("unknown printer %s\n", printer); 72512382Sralph continue; 72612382Sralph } 72712382Sralph stoppr(); 72812382Sralph } 72912382Sralph } 73012382Sralph 73112382Sralph stoppr() 73212382Sralph { 73312382Sralph register int fd; 73412382Sralph struct stat stbuf; 73512382Sralph 73612382Sralph bp = pbuf; 73712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 73812382Sralph SD = DEFSPOOL; 73912382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 74012382Sralph LO = DEFLOCK; 74112382Sralph (void) sprintf(line, "%s/%s", SD, LO); 74212382Sralph printf("%s:\n", printer); 74312382Sralph 74412382Sralph /* 74512382Sralph * Turn on the owner execute bit of the lock file to disable printing. 74612382Sralph */ 74712382Sralph if (stat(line, &stbuf) >= 0) { 74812382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 74912382Sralph printf("\tcannot disable printing\n"); 75012382Sralph else 75112382Sralph printf("\tprinting disabled\n"); 75212382Sralph } else if (errno == ENOENT) { 75313146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 75412382Sralph printf("\tcannot create lock file\n"); 75512382Sralph else { 75612382Sralph (void) close(fd); 75712382Sralph printf("\tprinting disabled\n"); 75812382Sralph } 75912382Sralph } else 76012382Sralph printf("\tcannot stat lock file\n"); 76112382Sralph } 76213727Sroot 76315719Sralph struct queue **queue; 76415719Sralph int nitems; 76515719Sralph time_t mtime; 76615719Sralph 76713727Sroot /* 76813727Sroot * Put the specified jobs at the top of printer queue. 76913727Sroot */ 77013727Sroot topq(argc, argv) 77113727Sroot char *argv[]; 77213727Sroot { 77315719Sralph register int n, i; 77413727Sroot struct stat stbuf; 77513727Sroot register char *cfname; 77615719Sralph int status, changed; 77713727Sroot 77815719Sralph if (argc < 3) { 77913727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 78013727Sroot return; 78113727Sroot } 78213727Sroot 78313727Sroot --argc; 78413727Sroot printer = *++argv; 78513727Sroot status = pgetent(line, printer); 78613727Sroot if (status < 0) { 78713727Sroot printf("cannot open printer description file\n"); 78813727Sroot return; 78914151Sralph } else if (status == 0) { 79013727Sroot printf("%s: unknown printer\n", printer); 79113727Sroot return; 79213727Sroot } 79313727Sroot bp = pbuf; 79413727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 79513727Sroot SD = DEFSPOOL; 79613727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 79713727Sroot LO = DEFLOCK; 79813727Sroot printf("%s:\n", printer); 79913727Sroot 80013727Sroot if (chdir(SD) < 0) { 80113727Sroot printf("\tcannot chdir to %s\n", SD); 80213727Sroot return; 80313727Sroot } 80413727Sroot nitems = getq(&queue); 80515719Sralph if (nitems == 0) 80615719Sralph return; 80715719Sralph changed = 0; 80815719Sralph mtime = queue[0]->q_time; 80915719Sralph for (i = argc; --i; ) { 81015719Sralph if (doarg(argv[i]) == 0) { 81115719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 81213727Sroot continue; 81315719Sralph } else 81414151Sralph changed++; 81513727Sroot } 81615719Sralph for (i = 0; i < nitems; i++) 81715719Sralph free(queue[i]); 81815719Sralph free(queue); 81915719Sralph if (!changed) { 82015719Sralph printf("\tqueue order unchanged\n"); 82115719Sralph return; 82213727Sroot } 82313727Sroot /* 82413727Sroot * Turn on the public execute bit of the lock file to 82513727Sroot * get lpd to rebuild the queue after the current job. 82613727Sroot */ 82714151Sralph if (changed && stat(LO, &stbuf) >= 0) 82814151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 82913727Sroot } 83013727Sroot 83115719Sralph /* 83215719Sralph * Reposition the job by changing the modification time of 83315719Sralph * the control file. 83413727Sroot */ 83515719Sralph touch(q) 83615719Sralph struct queue *q; 83713727Sroot { 83815719Sralph struct timeval tvp[2]; 83913727Sroot 84015719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 84115719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 84215719Sralph return(utimes(q->q_name, tvp)); 84313727Sroot } 84413727Sroot 84513727Sroot /* 84613727Sroot * Checks if specified job name is in the printer's queue. 84713727Sroot * Returns: negative (-1) if argument name is not in the queue. 84813727Sroot */ 84915719Sralph doarg(job) 85013727Sroot char *job; 85113727Sroot { 85215719Sralph register struct queue **qq; 85315719Sralph register int jobnum, n; 85415719Sralph register char *cp, *machine; 85515719Sralph int cnt = 0; 85614151Sralph FILE *fp; 85713727Sroot 85815719Sralph /* 85915719Sralph * Look for a job item consisting of system name, colon, number 86015719Sralph * (example: ucbarpa:114) 86115719Sralph */ 86215719Sralph if ((cp = index(job, ':')) != NULL) { 86315719Sralph machine = job; 86415719Sralph *cp++ = '\0'; 86515719Sralph job = cp; 86615719Sralph } else 86715719Sralph machine = NULL; 86815719Sralph 86915719Sralph /* 87015719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 87115719Sralph */ 87213727Sroot if (isdigit(*job)) { 87313727Sroot jobnum = 0; 87413727Sroot do 87513727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 87613727Sroot while (isdigit(*job)); 87715719Sralph for (qq = queue + nitems; --qq >= queue; ) { 87813727Sroot n = 0; 87915719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 88014151Sralph n = n * 10 + (*cp++ - '0'); 88115719Sralph if (jobnum != n) 88215719Sralph continue; 88315719Sralph if (*job && strcmp(job, cp) != 0) 88415719Sralph continue; 88515719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 88615719Sralph continue; 88715719Sralph if (touch(*qq) == 0) { 88815719Sralph printf("\tmoved %s\n", (*qq)->q_name); 88915719Sralph cnt++; 89015719Sralph } 89113727Sroot } 89215719Sralph return(cnt); 89315719Sralph } 89415719Sralph /* 89515719Sralph * Process item consisting of owner's name (example: henry). 89615719Sralph */ 89715719Sralph for (qq = queue + nitems; --qq >= queue; ) { 89815719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 89913727Sroot continue; 90015719Sralph while (getline(fp) > 0) 90115719Sralph if (line[0] == 'P') 90215719Sralph break; 90315719Sralph (void) fclose(fp); 90415719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 90515719Sralph continue; 90615719Sralph if (touch(*qq) == 0) { 90715719Sralph printf("\tmoved %s\n", (*qq)->q_name); 90815719Sralph cnt++; 90913727Sroot } 91013727Sroot } 91115719Sralph return(cnt); 91213727Sroot } 913*16755Sralph 914*16755Sralph /* 915*16755Sralph * Enable everything and start printer (undo `down'). 916*16755Sralph */ 917*16755Sralph up(argc, argv) 918*16755Sralph char *argv[]; 919*16755Sralph { 920*16755Sralph register int c, status; 921*16755Sralph register char *cp1, *cp2; 922*16755Sralph char prbuf[100]; 923*16755Sralph 924*16755Sralph if (argc == 1) { 925*16755Sralph printf("Usage: up {all | printer ...}\n"); 926*16755Sralph return; 927*16755Sralph } 928*16755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 929*16755Sralph printer = prbuf; 930*16755Sralph while (getprent(line) > 0) { 931*16755Sralph cp1 = prbuf; 932*16755Sralph cp2 = line; 933*16755Sralph while ((c = *cp2++) && c != '|' && c != ':') 934*16755Sralph *cp1++ = c; 935*16755Sralph *cp1 = '\0'; 936*16755Sralph startpr(2); 937*16755Sralph } 938*16755Sralph return; 939*16755Sralph } 940*16755Sralph while (--argc) { 941*16755Sralph printer = *++argv; 942*16755Sralph if ((status = pgetent(line, printer)) < 0) { 943*16755Sralph printf("cannot open printer description file\n"); 944*16755Sralph continue; 945*16755Sralph } else if (status == 0) { 946*16755Sralph printf("unknown printer %s\n", printer); 947*16755Sralph continue; 948*16755Sralph } 949*16755Sralph startpr(2); 950*16755Sralph } 951*16755Sralph } 952