122424Sdist /* 222424Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 5*42801Sbostic * %sccs.include.redist.c% 622424Sdist */ 722424Sdist 812382Sralph #ifndef lint 9*42801Sbostic static char sccsid[] = "@(#)cmds.c 5.7 (Berkeley) 06/01/90"; 1034203Sbostic #endif /* not lint */ 1112382Sralph 1212382Sralph /* 1315719Sralph * lpc -- line printer control program -- commands: 1412382Sralph */ 1512382Sralph 1612382Sralph #include "lp.h" 1715719Sralph #include <sys/time.h> 1837968Sbostic #include "pathnames.h" 1912382Sralph 2012382Sralph /* 2112382Sralph * kill an existing daemon and disable printing. 2212382Sralph */ 2312382Sralph abort(argc, argv) 2412382Sralph char *argv[]; 2512382Sralph { 2612382Sralph register int c, status; 2712382Sralph register char *cp1, *cp2; 2812382Sralph char prbuf[100]; 2912382Sralph 3012382Sralph if (argc == 1) { 3112382Sralph printf("Usage: abort {all | printer ...}\n"); 3212382Sralph return; 3312382Sralph } 3412382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 3512382Sralph printer = prbuf; 3612382Sralph while (getprent(line) > 0) { 3712382Sralph cp1 = prbuf; 3812382Sralph cp2 = line; 3912382Sralph while ((c = *cp2++) && c != '|' && c != ':') 4012382Sralph *cp1++ = c; 4112382Sralph *cp1 = '\0'; 4216755Sralph abortpr(1); 4312382Sralph } 4412382Sralph return; 4512382Sralph } 4612382Sralph while (--argc) { 4712382Sralph printer = *++argv; 4812382Sralph if ((status = pgetent(line, printer)) < 0) { 4912514Sralph printf("cannot open printer description file\n"); 5012382Sralph continue; 5112382Sralph } else if (status == 0) { 5212514Sralph printf("unknown printer %s\n", printer); 5312382Sralph continue; 5412382Sralph } 5516755Sralph abortpr(1); 5612382Sralph } 5712382Sralph } 5812382Sralph 5916755Sralph abortpr(dis) 6012382Sralph { 6112382Sralph register FILE *fp; 6212382Sralph struct stat stbuf; 6312382Sralph int pid, fd; 6412382Sralph 6512382Sralph bp = pbuf; 6612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 6737968Sbostic SD = _PATH_DEFSPOOL; 6812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 6912382Sralph LO = DEFLOCK; 7012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 7112382Sralph printf("%s:\n", printer); 7212382Sralph 7312382Sralph /* 7412382Sralph * Turn on the owner execute bit of the lock file to disable printing. 7512382Sralph */ 7616755Sralph if (dis) { 7716755Sralph if (stat(line, &stbuf) >= 0) { 7816755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 7916755Sralph printf("\tcannot disable printing\n"); 8038735Stef else { 8138735Stef upstat("printing disabled\n"); 8216755Sralph printf("\tprinting disabled\n"); 8338735Stef } 8416755Sralph } else if (errno == ENOENT) { 8516755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 8616755Sralph printf("\tcannot create lock file\n"); 8716755Sralph else { 8816755Sralph (void) close(fd); 8938735Stef upstat("printing disabled\n"); 9016755Sralph printf("\tprinting disabled\n"); 9116755Sralph printf("\tno daemon to abort\n"); 9216755Sralph } 9316755Sralph return; 9416755Sralph } else { 9516755Sralph printf("\tcannot stat lock file\n"); 9616755Sralph return; 9712382Sralph } 9812382Sralph } 9912382Sralph /* 10012382Sralph * Kill the current daemon to stop printing now. 10112382Sralph */ 10212382Sralph if ((fp = fopen(line, "r")) == NULL) { 10312382Sralph printf("\tcannot open lock file\n"); 10412382Sralph return; 10512382Sralph } 10613146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 10713168Sralph (void) fclose(fp); /* unlocks as well */ 10812382Sralph printf("\tno daemon to abort\n"); 10912382Sralph return; 11012382Sralph } 11112382Sralph (void) fclose(fp); 11216755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 11312382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 11412382Sralph else 11512382Sralph printf("\tdaemon (pid %d) killed\n", pid); 11612382Sralph } 11712382Sralph 11812382Sralph /* 11938735Stef * Write a message into the status file. 12038735Stef */ 12138735Stef upstat(msg) 12238735Stef char *msg; 12338735Stef { 12438735Stef register int fd; 12538735Stef char statfile[BUFSIZ]; 12638735Stef 12738735Stef bp = pbuf; 12838735Stef if ((ST = pgetstr("st", &bp)) == NULL) 12938735Stef ST = DEFSTAT; 13038735Stef (void) sprintf(statfile, "%s/%s", SD, ST); 13138735Stef umask(0); 13238735Stef fd = open(statfile, O_WRONLY|O_CREAT, 0664); 13338735Stef if (fd < 0 || flock(fd, LOCK_EX) < 0) { 13438735Stef printf("\tcannot create status file\n"); 13538735Stef return; 13638735Stef } 13738735Stef (void) ftruncate(fd, 0); 13838735Stef if (msg == (char *)NULL) 13938735Stef (void) write(fd, "\n", 1); 14038735Stef else 14138735Stef (void) write(fd, msg, strlen(msg)); 14238735Stef (void) close(fd); 14338735Stef } 14438735Stef 14538735Stef /* 14612382Sralph * Remove all spool files and temporaries from the spooling area. 14712382Sralph */ 14812382Sralph clean(argc, argv) 14912382Sralph char *argv[]; 15012382Sralph { 15112382Sralph register int c, status; 15212382Sralph register char *cp1, *cp2; 15312382Sralph char prbuf[100]; 15412382Sralph 15512382Sralph if (argc == 1) { 15612382Sralph printf("Usage: clean {all | printer ...}\n"); 15712382Sralph return; 15812382Sralph } 15912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 16012382Sralph printer = prbuf; 16112382Sralph while (getprent(line) > 0) { 16212382Sralph cp1 = prbuf; 16312382Sralph cp2 = line; 16412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 16512382Sralph *cp1++ = c; 16612382Sralph *cp1 = '\0'; 16712382Sralph cleanpr(); 16812382Sralph } 16912382Sralph return; 17012382Sralph } 17112382Sralph while (--argc) { 17212382Sralph printer = *++argv; 17312382Sralph if ((status = pgetent(line, printer)) < 0) { 17412514Sralph printf("cannot open printer description file\n"); 17512382Sralph continue; 17612382Sralph } else if (status == 0) { 17712514Sralph printf("unknown printer %s\n", printer); 17812382Sralph continue; 17912382Sralph } 18012382Sralph cleanpr(); 18112382Sralph } 18212382Sralph } 18312382Sralph 18415719Sralph select(d) 18515719Sralph struct direct *d; 18615719Sralph { 18715719Sralph int c = d->d_name[0]; 18815719Sralph 18915719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 19015719Sralph return(1); 19115719Sralph return(0); 19215719Sralph } 19315719Sralph 19415719Sralph /* 19515719Sralph * Comparison routine for scandir. Sort by job number and machine, then 19615719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 19715719Sralph */ 19815719Sralph sortq(d1, d2) 19915719Sralph struct direct **d1, **d2; 20015719Sralph { 20115719Sralph int c1, c2; 20215719Sralph 20315719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 20415719Sralph return(c1); 20515719Sralph c1 = (*d1)->d_name[0]; 20615719Sralph c2 = (*d2)->d_name[0]; 20715719Sralph if (c1 == c2) 20815719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 20915719Sralph if (c1 == 'c') 21015719Sralph return(-1); 21115719Sralph if (c1 == 'd' || c2 == 'c') 21215719Sralph return(1); 21315719Sralph return(-1); 21415719Sralph } 21515719Sralph 21615719Sralph /* 21715719Sralph * Remove incomplete jobs from spooling area. 21815719Sralph */ 21912382Sralph cleanpr() 22012382Sralph { 22115719Sralph register int i, n; 22215719Sralph register char *cp, *cp1, *lp; 22315719Sralph struct direct **queue; 22415719Sralph int nitems; 22512382Sralph 22612382Sralph bp = pbuf; 22712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 22837968Sbostic SD = _PATH_DEFSPOOL; 22912382Sralph printf("%s:\n", printer); 23012382Sralph 23115719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 23215719Sralph ; 23315719Sralph lp[-1] = '/'; 23415719Sralph 23515719Sralph nitems = scandir(SD, &queue, select, sortq); 23615719Sralph if (nitems < 0) { 23712382Sralph printf("\tcannot examine spool directory\n"); 23812382Sralph return; 23912382Sralph } 24015719Sralph if (nitems == 0) 24115719Sralph return; 24215719Sralph i = 0; 24315719Sralph do { 24415719Sralph cp = queue[i]->d_name; 24515719Sralph if (*cp == 'c') { 24615719Sralph n = 0; 24715719Sralph while (i + 1 < nitems) { 24815719Sralph cp1 = queue[i + 1]->d_name; 24915719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 25015719Sralph break; 25115719Sralph i++; 25215719Sralph n++; 25315719Sralph } 25415719Sralph if (n == 0) { 25515719Sralph strcpy(lp, cp); 25615719Sralph unlinkf(line); 25715719Sralph } 25815719Sralph } else { 25915719Sralph /* 26015719Sralph * Must be a df with no cf (otherwise, it would have 26115719Sralph * been skipped above) or a tf file (which can always 26215719Sralph * be removed). 26315719Sralph */ 26415719Sralph strcpy(lp, cp); 26515719Sralph unlinkf(line); 26612382Sralph } 26715719Sralph } while (++i < nitems); 26812382Sralph } 26915719Sralph 27015719Sralph unlinkf(name) 27115719Sralph char *name; 27215719Sralph { 27315719Sralph if (unlink(name) < 0) 27415719Sralph printf("\tcannot remove %s\n", name); 27515719Sralph else 27615719Sralph printf("\tremoved %s\n", name); 27715719Sralph } 27812382Sralph 27912382Sralph /* 28012382Sralph * Enable queuing to the printer (allow lpr's). 28112382Sralph */ 28212382Sralph enable(argc, argv) 28312382Sralph char *argv[]; 28412382Sralph { 28512382Sralph register int c, status; 28612382Sralph register char *cp1, *cp2; 28712382Sralph char prbuf[100]; 28812382Sralph 28912382Sralph if (argc == 1) { 29012382Sralph printf("Usage: enable {all | printer ...}\n"); 29112382Sralph return; 29212382Sralph } 29312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 29412382Sralph printer = prbuf; 29512382Sralph while (getprent(line) > 0) { 29612382Sralph cp1 = prbuf; 29712382Sralph cp2 = line; 29812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 29912382Sralph *cp1++ = c; 30012382Sralph *cp1 = '\0'; 30112382Sralph enablepr(); 30212382Sralph } 30312382Sralph return; 30412382Sralph } 30512382Sralph while (--argc) { 30612382Sralph printer = *++argv; 30712382Sralph if ((status = pgetent(line, printer)) < 0) { 30812514Sralph printf("cannot open printer description file\n"); 30912382Sralph continue; 31012382Sralph } else if (status == 0) { 31112514Sralph printf("unknown printer %s\n", printer); 31212382Sralph continue; 31312382Sralph } 31412382Sralph enablepr(); 31512382Sralph } 31612382Sralph } 31712382Sralph 31812382Sralph enablepr() 31912382Sralph { 32012382Sralph struct stat stbuf; 32112382Sralph 32212382Sralph bp = pbuf; 32312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 32437968Sbostic SD = _PATH_DEFSPOOL; 32512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 32612382Sralph LO = DEFLOCK; 32712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 32812382Sralph printf("%s:\n", printer); 32912382Sralph 33012382Sralph /* 33112382Sralph * Turn off the group execute bit of the lock file to enable queuing. 33212382Sralph */ 33312382Sralph if (stat(line, &stbuf) >= 0) { 33412382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 33512514Sralph printf("\tcannot enable queuing\n"); 33612382Sralph else 33712382Sralph printf("\tqueuing enabled\n"); 33812382Sralph } 33912382Sralph } 34012382Sralph 34112382Sralph /* 34212382Sralph * Disable queuing. 34312382Sralph */ 34412382Sralph disable(argc, argv) 34512382Sralph char *argv[]; 34612382Sralph { 34712382Sralph register int c, status; 34812382Sralph register char *cp1, *cp2; 34912382Sralph char prbuf[100]; 35012382Sralph 35112382Sralph if (argc == 1) { 35212382Sralph printf("Usage: disable {all | printer ...}\n"); 35312382Sralph return; 35412382Sralph } 35512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 35612382Sralph printer = prbuf; 35712382Sralph while (getprent(line) > 0) { 35812382Sralph cp1 = prbuf; 35912382Sralph cp2 = line; 36012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 36112382Sralph *cp1++ = c; 36212382Sralph *cp1 = '\0'; 36312382Sralph disablepr(); 36412382Sralph } 36512382Sralph return; 36612382Sralph } 36712382Sralph while (--argc) { 36812382Sralph printer = *++argv; 36912382Sralph if ((status = pgetent(line, printer)) < 0) { 37012514Sralph printf("cannot open printer description file\n"); 37112382Sralph continue; 37212382Sralph } else if (status == 0) { 37312514Sralph printf("unknown printer %s\n", printer); 37412382Sralph continue; 37512382Sralph } 37612382Sralph disablepr(); 37712382Sralph } 37812382Sralph } 37912382Sralph 38012382Sralph disablepr() 38112382Sralph { 38212382Sralph register int fd; 38312382Sralph struct stat stbuf; 38412382Sralph 38512382Sralph bp = pbuf; 38612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 38737968Sbostic SD = _PATH_DEFSPOOL; 38812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 38912382Sralph LO = DEFLOCK; 39012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 39112382Sralph printf("%s:\n", printer); 39212382Sralph /* 39312382Sralph * Turn on the group execute bit of the lock file to disable queuing. 39412382Sralph */ 39512382Sralph if (stat(line, &stbuf) >= 0) { 39612382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 39712382Sralph printf("\tcannot disable queuing\n"); 39812382Sralph else 39912382Sralph printf("\tqueuing disabled\n"); 40012382Sralph } else if (errno == ENOENT) { 40113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 40212382Sralph printf("\tcannot create lock file\n"); 40312382Sralph else { 40412382Sralph (void) close(fd); 40512382Sralph printf("\tqueuing disabled\n"); 40612382Sralph } 40712382Sralph return; 40812382Sralph } else 40912382Sralph printf("\tcannot stat lock file\n"); 41012382Sralph } 41112382Sralph 41212382Sralph /* 41315907Sralph * Disable queuing and printing and put a message into the status file 41415907Sralph * (reason for being down). 41515907Sralph */ 41615907Sralph down(argc, argv) 41715907Sralph char *argv[]; 41815907Sralph { 41915907Sralph register int c, status; 42015907Sralph register char *cp1, *cp2; 42115907Sralph char prbuf[100]; 42215907Sralph 42315907Sralph if (argc == 1) { 42416204Sralph printf("Usage: down {all | printer} [message ...]\n"); 42515907Sralph return; 42615907Sralph } 42715907Sralph if (!strcmp(argv[1], "all")) { 42815907Sralph printer = prbuf; 42915907Sralph while (getprent(line) > 0) { 43015907Sralph cp1 = prbuf; 43115907Sralph cp2 = line; 43215907Sralph while ((c = *cp2++) && c != '|' && c != ':') 43315907Sralph *cp1++ = c; 43415907Sralph *cp1 = '\0'; 43515907Sralph putmsg(argc - 2, argv + 2); 43615907Sralph } 43715907Sralph return; 43815907Sralph } 43915907Sralph printer = argv[1]; 44015907Sralph if ((status = pgetent(line, printer)) < 0) { 44115907Sralph printf("cannot open printer description file\n"); 44215907Sralph return; 44315907Sralph } else if (status == 0) { 44415907Sralph printf("unknown printer %s\n", printer); 44515907Sralph return; 44615907Sralph } 44715907Sralph putmsg(argc - 2, argv + 2); 44815907Sralph } 44915907Sralph 45015907Sralph putmsg(argc, argv) 45115907Sralph char **argv; 45215907Sralph { 45315907Sralph register int fd; 45415907Sralph register char *cp1, *cp2; 45515907Sralph char buf[1024]; 45615907Sralph struct stat stbuf; 45715907Sralph 45815907Sralph bp = pbuf; 45915907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 46037968Sbostic SD = _PATH_DEFSPOOL; 46115907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 46215907Sralph LO = DEFLOCK; 46315907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 46415907Sralph ST = DEFSTAT; 46515907Sralph printf("%s:\n", printer); 46615907Sralph /* 46715907Sralph * Turn on the group execute bit of the lock file to disable queuing and 46815907Sralph * turn on the owner execute bit of the lock file to disable printing. 46915907Sralph */ 47015907Sralph (void) sprintf(line, "%s/%s", SD, LO); 47115907Sralph if (stat(line, &stbuf) >= 0) { 47215907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 47315907Sralph printf("\tcannot disable queuing\n"); 47415907Sralph else 47515907Sralph printf("\tprinter and queuing disabled\n"); 47615907Sralph } else if (errno == ENOENT) { 47715907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 47815907Sralph printf("\tcannot create lock file\n"); 47915907Sralph else { 48015907Sralph (void) close(fd); 48115907Sralph printf("\tprinter and queuing disabled\n"); 48215907Sralph } 48315907Sralph return; 48415907Sralph } else 48515907Sralph printf("\tcannot stat lock file\n"); 48615907Sralph /* 48715907Sralph * Write the message into the status file. 48815907Sralph */ 48915907Sralph (void) sprintf(line, "%s/%s", SD, ST); 49015907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 49115907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 49215907Sralph printf("\tcannot create status file\n"); 49315907Sralph return; 49415907Sralph } 49515907Sralph (void) ftruncate(fd, 0); 49616204Sralph if (argc <= 0) { 49716204Sralph (void) write(fd, "\n", 1); 49816204Sralph (void) close(fd); 49916204Sralph return; 50016204Sralph } 50115907Sralph cp1 = buf; 50215907Sralph while (--argc >= 0) { 50315907Sralph cp2 = *argv++; 50415907Sralph while (*cp1++ = *cp2++) 50515907Sralph ; 50615907Sralph cp1[-1] = ' '; 50715907Sralph } 50815907Sralph cp1[-1] = '\n'; 50915907Sralph *cp1 = '\0'; 51015907Sralph (void) write(fd, buf, strlen(buf)); 51115907Sralph (void) close(fd); 51215907Sralph } 51315907Sralph 51415907Sralph /* 51512382Sralph * Exit lpc 51612382Sralph */ 51712382Sralph quit(argc, argv) 51812382Sralph char *argv[]; 51912382Sralph { 52012382Sralph exit(0); 52112382Sralph } 52212382Sralph 52312382Sralph /* 52416755Sralph * Kill and restart the daemon. 52512382Sralph */ 52612382Sralph restart(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: restart {all | printer ...}\n"); 53512382Sralph return; 53612382Sralph } 53712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 53812382Sralph printer = prbuf; 53912382Sralph while (getprent(line) > 0) { 54012382Sralph cp1 = prbuf; 54112382Sralph cp2 = line; 54212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 54312382Sralph *cp1++ = c; 54412382Sralph *cp1 = '\0'; 54516755Sralph abortpr(0); 54612382Sralph startpr(0); 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 } 55916755Sralph abortpr(0); 56012382Sralph startpr(0); 56112382Sralph } 56212382Sralph } 56312382Sralph 56412382Sralph /* 56512382Sralph * Enable printing on the specified printer and startup the daemon. 56612382Sralph */ 56712382Sralph start(argc, argv) 56812382Sralph char *argv[]; 56912382Sralph { 57012382Sralph register int c, status; 57112382Sralph register char *cp1, *cp2; 57212382Sralph char prbuf[100]; 57312382Sralph 57412382Sralph if (argc == 1) { 57512382Sralph printf("Usage: start {all | printer ...}\n"); 57612382Sralph return; 57712382Sralph } 57812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 57912382Sralph printer = prbuf; 58012382Sralph while (getprent(line) > 0) { 58112382Sralph cp1 = prbuf; 58212382Sralph cp2 = line; 58312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 58412382Sralph *cp1++ = c; 58512382Sralph *cp1 = '\0'; 58612382Sralph startpr(1); 58712382Sralph } 58812382Sralph return; 58912382Sralph } 59012382Sralph while (--argc) { 59112382Sralph printer = *++argv; 59212382Sralph if ((status = pgetent(line, printer)) < 0) { 59312514Sralph printf("cannot open printer description file\n"); 59412382Sralph continue; 59512382Sralph } else if (status == 0) { 59612514Sralph printf("unknown printer %s\n", printer); 59712382Sralph continue; 59812382Sralph } 59912382Sralph startpr(1); 60012382Sralph } 60112382Sralph } 60212382Sralph 60312382Sralph startpr(enable) 60412382Sralph { 60512382Sralph struct stat stbuf; 60612382Sralph 60712382Sralph bp = pbuf; 60812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 60937968Sbostic SD = _PATH_DEFSPOOL; 61012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 61112382Sralph LO = DEFLOCK; 61212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 61312382Sralph printf("%s:\n", printer); 61412382Sralph 61512382Sralph /* 61612382Sralph * Turn off the owner execute bit of the lock file to enable printing. 61712382Sralph */ 61812382Sralph if (enable && stat(line, &stbuf) >= 0) { 61916771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 62012382Sralph printf("\tcannot enable printing\n"); 62112382Sralph else 62212382Sralph printf("\tprinting enabled\n"); 62312382Sralph } 62413727Sroot if (!startdaemon(printer)) 62512382Sralph printf("\tcouldn't start daemon\n"); 62612382Sralph else 62712382Sralph printf("\tdaemon started\n"); 62812382Sralph } 62912382Sralph 63012382Sralph /* 63112382Sralph * Print the status of each queue listed or all the queues. 63212382Sralph */ 63312382Sralph status(argc, argv) 63412382Sralph char *argv[]; 63512382Sralph { 63612382Sralph register int c, status; 63712382Sralph register char *cp1, *cp2; 63812382Sralph char prbuf[100]; 63912382Sralph 64012382Sralph if (argc == 1) { 64112382Sralph printer = prbuf; 64212382Sralph while (getprent(line) > 0) { 64312382Sralph cp1 = prbuf; 64412382Sralph cp2 = line; 64512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 64612382Sralph *cp1++ = c; 64712382Sralph *cp1 = '\0'; 64812382Sralph prstat(); 64912382Sralph } 65012382Sralph return; 65112382Sralph } 65212382Sralph while (--argc) { 65312382Sralph printer = *++argv; 65412382Sralph if ((status = pgetent(line, printer)) < 0) { 65512514Sralph printf("cannot open printer description file\n"); 65612382Sralph continue; 65712382Sralph } else if (status == 0) { 65812514Sralph printf("unknown printer %s\n", printer); 65912382Sralph continue; 66012382Sralph } 66112382Sralph prstat(); 66212382Sralph } 66312382Sralph } 66412382Sralph 66512382Sralph /* 66612382Sralph * Print the status of the printer queue. 66712382Sralph */ 66812382Sralph prstat() 66912382Sralph { 67012382Sralph struct stat stbuf; 67112382Sralph register int fd, i; 67212382Sralph register struct direct *dp; 67312382Sralph DIR *dirp; 67412382Sralph 67512382Sralph bp = pbuf; 67612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 67737968Sbostic SD = _PATH_DEFSPOOL; 67812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 67912382Sralph LO = DEFLOCK; 68012382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 68112382Sralph ST = DEFSTAT; 68212382Sralph printf("%s:\n", printer); 68312382Sralph (void) sprintf(line, "%s/%s", SD, LO); 68412382Sralph if (stat(line, &stbuf) >= 0) { 68512382Sralph printf("\tqueuing is %s\n", 68612382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 68712382Sralph printf("\tprinting is %s\n", 68812382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 68912382Sralph } else { 69012382Sralph printf("\tqueuing is enabled\n"); 69112382Sralph printf("\tprinting is enabled\n"); 69212382Sralph } 69312382Sralph if ((dirp = opendir(SD)) == NULL) { 69412382Sralph printf("\tcannot examine spool directory\n"); 69512382Sralph return; 69612382Sralph } 69712382Sralph i = 0; 69812382Sralph while ((dp = readdir(dirp)) != NULL) { 69912382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 70012382Sralph i++; 70112382Sralph } 70212382Sralph closedir(dirp); 70312382Sralph if (i == 0) 70412382Sralph printf("\tno entries\n"); 70512382Sralph else if (i == 1) 70612382Sralph printf("\t1 entry in spool area\n"); 70712382Sralph else 70812382Sralph printf("\t%d entries in spool area\n", i); 70913146Ssam fd = open(line, O_RDONLY); 71013146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 71113168Sralph (void) close(fd); /* unlocks as well */ 71212382Sralph printf("\tno daemon present\n"); 71312382Sralph return; 71412382Sralph } 71512382Sralph (void) close(fd); 71612382Sralph putchar('\t'); 71712382Sralph (void) sprintf(line, "%s/%s", SD, ST); 71813146Ssam fd = open(line, O_RDONLY); 71913146Ssam if (fd >= 0) { 72013146Ssam (void) flock(fd, LOCK_SH); 72112382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 72212382Sralph (void) fwrite(line, 1, i, stdout); 72313168Sralph (void) close(fd); /* unlocks as well */ 72412382Sralph } 72512382Sralph } 72612382Sralph 72712382Sralph /* 72812382Sralph * Stop the specified daemon after completing the current job and disable 72912382Sralph * printing. 73012382Sralph */ 73112382Sralph stop(argc, argv) 73212382Sralph char *argv[]; 73312382Sralph { 73412382Sralph register int c, status; 73512382Sralph register char *cp1, *cp2; 73612382Sralph char prbuf[100]; 73712382Sralph 73812382Sralph if (argc == 1) { 73912382Sralph printf("Usage: stop {all | printer ...}\n"); 74012382Sralph return; 74112382Sralph } 74212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 74312382Sralph printer = prbuf; 74412382Sralph while (getprent(line) > 0) { 74512382Sralph cp1 = prbuf; 74612382Sralph cp2 = line; 74712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 74812382Sralph *cp1++ = c; 74912382Sralph *cp1 = '\0'; 75012382Sralph stoppr(); 75112382Sralph } 75212382Sralph return; 75312382Sralph } 75412382Sralph while (--argc) { 75512382Sralph printer = *++argv; 75612382Sralph if ((status = pgetent(line, printer)) < 0) { 75712514Sralph printf("cannot open printer description file\n"); 75812382Sralph continue; 75912382Sralph } else if (status == 0) { 76012514Sralph printf("unknown printer %s\n", printer); 76112382Sralph continue; 76212382Sralph } 76312382Sralph stoppr(); 76412382Sralph } 76512382Sralph } 76612382Sralph 76712382Sralph stoppr() 76812382Sralph { 76912382Sralph register int fd; 77012382Sralph struct stat stbuf; 77112382Sralph 77212382Sralph bp = pbuf; 77312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 77437968Sbostic SD = _PATH_DEFSPOOL; 77512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 77612382Sralph LO = DEFLOCK; 77712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 77812382Sralph printf("%s:\n", printer); 77912382Sralph 78012382Sralph /* 78112382Sralph * Turn on the owner execute bit of the lock file to disable printing. 78212382Sralph */ 78312382Sralph if (stat(line, &stbuf) >= 0) { 78412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 78512382Sralph printf("\tcannot disable printing\n"); 78638735Stef else { 78738735Stef upstat("printing disabled\n"); 78812382Sralph printf("\tprinting disabled\n"); 78938735Stef } 79012382Sralph } else if (errno == ENOENT) { 79113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 79212382Sralph printf("\tcannot create lock file\n"); 79312382Sralph else { 79412382Sralph (void) close(fd); 79538735Stef upstat("printing disabled\n"); 79612382Sralph printf("\tprinting disabled\n"); 79712382Sralph } 79812382Sralph } else 79912382Sralph printf("\tcannot stat lock file\n"); 80012382Sralph } 80113727Sroot 80215719Sralph struct queue **queue; 80315719Sralph int nitems; 80415719Sralph time_t mtime; 80515719Sralph 80613727Sroot /* 80713727Sroot * Put the specified jobs at the top of printer queue. 80813727Sroot */ 80913727Sroot topq(argc, argv) 81013727Sroot char *argv[]; 81113727Sroot { 81215719Sralph register int n, i; 81313727Sroot struct stat stbuf; 81413727Sroot register char *cfname; 81515719Sralph int status, changed; 81613727Sroot 81715719Sralph if (argc < 3) { 81813727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 81913727Sroot return; 82013727Sroot } 82113727Sroot 82213727Sroot --argc; 82313727Sroot printer = *++argv; 82413727Sroot status = pgetent(line, printer); 82513727Sroot if (status < 0) { 82613727Sroot printf("cannot open printer description file\n"); 82713727Sroot return; 82814151Sralph } else if (status == 0) { 82913727Sroot printf("%s: unknown printer\n", printer); 83013727Sroot return; 83113727Sroot } 83213727Sroot bp = pbuf; 83313727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 83437968Sbostic SD = _PATH_DEFSPOOL; 83513727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 83613727Sroot LO = DEFLOCK; 83713727Sroot printf("%s:\n", printer); 83813727Sroot 83913727Sroot if (chdir(SD) < 0) { 84013727Sroot printf("\tcannot chdir to %s\n", SD); 84113727Sroot return; 84213727Sroot } 84313727Sroot nitems = getq(&queue); 84415719Sralph if (nitems == 0) 84515719Sralph return; 84615719Sralph changed = 0; 84715719Sralph mtime = queue[0]->q_time; 84815719Sralph for (i = argc; --i; ) { 84915719Sralph if (doarg(argv[i]) == 0) { 85015719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 85113727Sroot continue; 85215719Sralph } else 85314151Sralph changed++; 85413727Sroot } 85515719Sralph for (i = 0; i < nitems; i++) 85615719Sralph free(queue[i]); 85715719Sralph free(queue); 85815719Sralph if (!changed) { 85915719Sralph printf("\tqueue order unchanged\n"); 86015719Sralph return; 86113727Sroot } 86213727Sroot /* 86313727Sroot * Turn on the public execute bit of the lock file to 86413727Sroot * get lpd to rebuild the queue after the current job. 86513727Sroot */ 86614151Sralph if (changed && stat(LO, &stbuf) >= 0) 86714151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 86813727Sroot } 86913727Sroot 87015719Sralph /* 87115719Sralph * Reposition the job by changing the modification time of 87215719Sralph * the control file. 87313727Sroot */ 87415719Sralph touch(q) 87515719Sralph struct queue *q; 87613727Sroot { 87715719Sralph struct timeval tvp[2]; 87813727Sroot 87915719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 88015719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 88115719Sralph return(utimes(q->q_name, tvp)); 88213727Sroot } 88313727Sroot 88413727Sroot /* 88513727Sroot * Checks if specified job name is in the printer's queue. 88613727Sroot * Returns: negative (-1) if argument name is not in the queue. 88713727Sroot */ 88815719Sralph doarg(job) 88913727Sroot char *job; 89013727Sroot { 89115719Sralph register struct queue **qq; 89215719Sralph register int jobnum, n; 89315719Sralph register char *cp, *machine; 89415719Sralph int cnt = 0; 89514151Sralph FILE *fp; 89613727Sroot 89715719Sralph /* 89815719Sralph * Look for a job item consisting of system name, colon, number 89915719Sralph * (example: ucbarpa:114) 90015719Sralph */ 90115719Sralph if ((cp = index(job, ':')) != NULL) { 90215719Sralph machine = job; 90315719Sralph *cp++ = '\0'; 90415719Sralph job = cp; 90515719Sralph } else 90615719Sralph machine = NULL; 90715719Sralph 90815719Sralph /* 90915719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 91015719Sralph */ 91113727Sroot if (isdigit(*job)) { 91213727Sroot jobnum = 0; 91313727Sroot do 91413727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 91513727Sroot while (isdigit(*job)); 91615719Sralph for (qq = queue + nitems; --qq >= queue; ) { 91713727Sroot n = 0; 91815719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 91914151Sralph n = n * 10 + (*cp++ - '0'); 92015719Sralph if (jobnum != n) 92115719Sralph continue; 92215719Sralph if (*job && strcmp(job, cp) != 0) 92315719Sralph continue; 92415719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 92515719Sralph continue; 92615719Sralph if (touch(*qq) == 0) { 92715719Sralph printf("\tmoved %s\n", (*qq)->q_name); 92815719Sralph cnt++; 92915719Sralph } 93013727Sroot } 93115719Sralph return(cnt); 93215719Sralph } 93315719Sralph /* 93415719Sralph * Process item consisting of owner's name (example: henry). 93515719Sralph */ 93615719Sralph for (qq = queue + nitems; --qq >= queue; ) { 93715719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 93813727Sroot continue; 93915719Sralph while (getline(fp) > 0) 94015719Sralph if (line[0] == 'P') 94115719Sralph break; 94215719Sralph (void) fclose(fp); 94315719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 94415719Sralph continue; 94515719Sralph if (touch(*qq) == 0) { 94615719Sralph printf("\tmoved %s\n", (*qq)->q_name); 94715719Sralph cnt++; 94813727Sroot } 94913727Sroot } 95015719Sralph return(cnt); 95113727Sroot } 95216755Sralph 95316755Sralph /* 95416755Sralph * Enable everything and start printer (undo `down'). 95516755Sralph */ 95616755Sralph up(argc, argv) 95716755Sralph char *argv[]; 95816755Sralph { 95916755Sralph register int c, status; 96016755Sralph register char *cp1, *cp2; 96116755Sralph char prbuf[100]; 96216755Sralph 96316755Sralph if (argc == 1) { 96416755Sralph printf("Usage: up {all | printer ...}\n"); 96516755Sralph return; 96616755Sralph } 96716755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 96816755Sralph printer = prbuf; 96916755Sralph while (getprent(line) > 0) { 97016755Sralph cp1 = prbuf; 97116755Sralph cp2 = line; 97216755Sralph while ((c = *cp2++) && c != '|' && c != ':') 97316755Sralph *cp1++ = c; 97416755Sralph *cp1 = '\0'; 97516755Sralph startpr(2); 97616755Sralph } 97716755Sralph return; 97816755Sralph } 97916755Sralph while (--argc) { 98016755Sralph printer = *++argv; 98116755Sralph if ((status = pgetent(line, printer)) < 0) { 98216755Sralph printf("cannot open printer description file\n"); 98316755Sralph continue; 98416755Sralph } else if (status == 0) { 98516755Sralph printf("unknown printer %s\n", printer); 98616755Sralph continue; 98716755Sralph } 98816755Sralph startpr(2); 98916755Sralph } 99016755Sralph } 991