122424Sdist /* 222424Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 534203Sbostic * Redistribution and use in source and binary forms are permitted 634936Sbostic * provided that the above copyright notice and this paragraph are 734936Sbostic * duplicated in all such forms and that any documentation, 834936Sbostic * advertising materials, and other materials related to such 934936Sbostic * distribution and use acknowledge that the software was developed 1034936Sbostic * by the University of California, Berkeley. The name of the 1134936Sbostic * University may not be used to endorse or promote products derived 1234936Sbostic * from this software without specific prior written permission. 1334936Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434936Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534936Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622424Sdist */ 1722424Sdist 1812382Sralph #ifndef lint 19*38735Stef static char sccsid[] = "@(#)cmds.c 5.6 (Berkeley) 08/22/89"; 2034203Sbostic #endif /* not lint */ 2112382Sralph 2212382Sralph /* 2315719Sralph * lpc -- line printer control program -- commands: 2412382Sralph */ 2512382Sralph 2612382Sralph #include "lp.h" 2715719Sralph #include <sys/time.h> 2837968Sbostic #include "pathnames.h" 2912382Sralph 3012382Sralph /* 3112382Sralph * kill an existing daemon and disable printing. 3212382Sralph */ 3312382Sralph abort(argc, argv) 3412382Sralph char *argv[]; 3512382Sralph { 3612382Sralph register int c, status; 3712382Sralph register char *cp1, *cp2; 3812382Sralph char prbuf[100]; 3912382Sralph 4012382Sralph if (argc == 1) { 4112382Sralph printf("Usage: abort {all | printer ...}\n"); 4212382Sralph return; 4312382Sralph } 4412382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 4512382Sralph printer = prbuf; 4612382Sralph while (getprent(line) > 0) { 4712382Sralph cp1 = prbuf; 4812382Sralph cp2 = line; 4912382Sralph while ((c = *cp2++) && c != '|' && c != ':') 5012382Sralph *cp1++ = c; 5112382Sralph *cp1 = '\0'; 5216755Sralph abortpr(1); 5312382Sralph } 5412382Sralph return; 5512382Sralph } 5612382Sralph while (--argc) { 5712382Sralph printer = *++argv; 5812382Sralph if ((status = pgetent(line, printer)) < 0) { 5912514Sralph printf("cannot open printer description file\n"); 6012382Sralph continue; 6112382Sralph } else if (status == 0) { 6212514Sralph printf("unknown printer %s\n", printer); 6312382Sralph continue; 6412382Sralph } 6516755Sralph abortpr(1); 6612382Sralph } 6712382Sralph } 6812382Sralph 6916755Sralph abortpr(dis) 7012382Sralph { 7112382Sralph register FILE *fp; 7212382Sralph struct stat stbuf; 7312382Sralph int pid, fd; 7412382Sralph 7512382Sralph bp = pbuf; 7612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 7737968Sbostic SD = _PATH_DEFSPOOL; 7812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 7912382Sralph LO = DEFLOCK; 8012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 8112382Sralph printf("%s:\n", printer); 8212382Sralph 8312382Sralph /* 8412382Sralph * Turn on the owner execute bit of the lock file to disable printing. 8512382Sralph */ 8616755Sralph if (dis) { 8716755Sralph if (stat(line, &stbuf) >= 0) { 8816755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 8916755Sralph printf("\tcannot disable printing\n"); 90*38735Stef else { 91*38735Stef upstat("printing disabled\n"); 9216755Sralph printf("\tprinting disabled\n"); 93*38735Stef } 9416755Sralph } else if (errno == ENOENT) { 9516755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 9616755Sralph printf("\tcannot create lock file\n"); 9716755Sralph else { 9816755Sralph (void) close(fd); 99*38735Stef upstat("printing disabled\n"); 10016755Sralph printf("\tprinting disabled\n"); 10116755Sralph printf("\tno daemon to abort\n"); 10216755Sralph } 10316755Sralph return; 10416755Sralph } else { 10516755Sralph printf("\tcannot stat lock file\n"); 10616755Sralph return; 10712382Sralph } 10812382Sralph } 10912382Sralph /* 11012382Sralph * Kill the current daemon to stop printing now. 11112382Sralph */ 11212382Sralph if ((fp = fopen(line, "r")) == NULL) { 11312382Sralph printf("\tcannot open lock file\n"); 11412382Sralph return; 11512382Sralph } 11613146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 11713168Sralph (void) fclose(fp); /* unlocks as well */ 11812382Sralph printf("\tno daemon to abort\n"); 11912382Sralph return; 12012382Sralph } 12112382Sralph (void) fclose(fp); 12216755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 12312382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 12412382Sralph else 12512382Sralph printf("\tdaemon (pid %d) killed\n", pid); 12612382Sralph } 12712382Sralph 12812382Sralph /* 129*38735Stef * Write a message into the status file. 130*38735Stef */ 131*38735Stef upstat(msg) 132*38735Stef char *msg; 133*38735Stef { 134*38735Stef register int fd; 135*38735Stef char statfile[BUFSIZ]; 136*38735Stef 137*38735Stef bp = pbuf; 138*38735Stef if ((ST = pgetstr("st", &bp)) == NULL) 139*38735Stef ST = DEFSTAT; 140*38735Stef (void) sprintf(statfile, "%s/%s", SD, ST); 141*38735Stef umask(0); 142*38735Stef fd = open(statfile, O_WRONLY|O_CREAT, 0664); 143*38735Stef if (fd < 0 || flock(fd, LOCK_EX) < 0) { 144*38735Stef printf("\tcannot create status file\n"); 145*38735Stef return; 146*38735Stef } 147*38735Stef (void) ftruncate(fd, 0); 148*38735Stef if (msg == (char *)NULL) 149*38735Stef (void) write(fd, "\n", 1); 150*38735Stef else 151*38735Stef (void) write(fd, msg, strlen(msg)); 152*38735Stef (void) close(fd); 153*38735Stef } 154*38735Stef 155*38735Stef /* 15612382Sralph * Remove all spool files and temporaries from the spooling area. 15712382Sralph */ 15812382Sralph clean(argc, argv) 15912382Sralph char *argv[]; 16012382Sralph { 16112382Sralph register int c, status; 16212382Sralph register char *cp1, *cp2; 16312382Sralph char prbuf[100]; 16412382Sralph 16512382Sralph if (argc == 1) { 16612382Sralph printf("Usage: clean {all | printer ...}\n"); 16712382Sralph return; 16812382Sralph } 16912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 17012382Sralph printer = prbuf; 17112382Sralph while (getprent(line) > 0) { 17212382Sralph cp1 = prbuf; 17312382Sralph cp2 = line; 17412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 17512382Sralph *cp1++ = c; 17612382Sralph *cp1 = '\0'; 17712382Sralph cleanpr(); 17812382Sralph } 17912382Sralph return; 18012382Sralph } 18112382Sralph while (--argc) { 18212382Sralph printer = *++argv; 18312382Sralph if ((status = pgetent(line, printer)) < 0) { 18412514Sralph printf("cannot open printer description file\n"); 18512382Sralph continue; 18612382Sralph } else if (status == 0) { 18712514Sralph printf("unknown printer %s\n", printer); 18812382Sralph continue; 18912382Sralph } 19012382Sralph cleanpr(); 19112382Sralph } 19212382Sralph } 19312382Sralph 19415719Sralph select(d) 19515719Sralph struct direct *d; 19615719Sralph { 19715719Sralph int c = d->d_name[0]; 19815719Sralph 19915719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 20015719Sralph return(1); 20115719Sralph return(0); 20215719Sralph } 20315719Sralph 20415719Sralph /* 20515719Sralph * Comparison routine for scandir. Sort by job number and machine, then 20615719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 20715719Sralph */ 20815719Sralph sortq(d1, d2) 20915719Sralph struct direct **d1, **d2; 21015719Sralph { 21115719Sralph int c1, c2; 21215719Sralph 21315719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 21415719Sralph return(c1); 21515719Sralph c1 = (*d1)->d_name[0]; 21615719Sralph c2 = (*d2)->d_name[0]; 21715719Sralph if (c1 == c2) 21815719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 21915719Sralph if (c1 == 'c') 22015719Sralph return(-1); 22115719Sralph if (c1 == 'd' || c2 == 'c') 22215719Sralph return(1); 22315719Sralph return(-1); 22415719Sralph } 22515719Sralph 22615719Sralph /* 22715719Sralph * Remove incomplete jobs from spooling area. 22815719Sralph */ 22912382Sralph cleanpr() 23012382Sralph { 23115719Sralph register int i, n; 23215719Sralph register char *cp, *cp1, *lp; 23315719Sralph struct direct **queue; 23415719Sralph int nitems; 23512382Sralph 23612382Sralph bp = pbuf; 23712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 23837968Sbostic SD = _PATH_DEFSPOOL; 23912382Sralph printf("%s:\n", printer); 24012382Sralph 24115719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 24215719Sralph ; 24315719Sralph lp[-1] = '/'; 24415719Sralph 24515719Sralph nitems = scandir(SD, &queue, select, sortq); 24615719Sralph if (nitems < 0) { 24712382Sralph printf("\tcannot examine spool directory\n"); 24812382Sralph return; 24912382Sralph } 25015719Sralph if (nitems == 0) 25115719Sralph return; 25215719Sralph i = 0; 25315719Sralph do { 25415719Sralph cp = queue[i]->d_name; 25515719Sralph if (*cp == 'c') { 25615719Sralph n = 0; 25715719Sralph while (i + 1 < nitems) { 25815719Sralph cp1 = queue[i + 1]->d_name; 25915719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 26015719Sralph break; 26115719Sralph i++; 26215719Sralph n++; 26315719Sralph } 26415719Sralph if (n == 0) { 26515719Sralph strcpy(lp, cp); 26615719Sralph unlinkf(line); 26715719Sralph } 26815719Sralph } else { 26915719Sralph /* 27015719Sralph * Must be a df with no cf (otherwise, it would have 27115719Sralph * been skipped above) or a tf file (which can always 27215719Sralph * be removed). 27315719Sralph */ 27415719Sralph strcpy(lp, cp); 27515719Sralph unlinkf(line); 27612382Sralph } 27715719Sralph } while (++i < nitems); 27812382Sralph } 27915719Sralph 28015719Sralph unlinkf(name) 28115719Sralph char *name; 28215719Sralph { 28315719Sralph if (unlink(name) < 0) 28415719Sralph printf("\tcannot remove %s\n", name); 28515719Sralph else 28615719Sralph printf("\tremoved %s\n", name); 28715719Sralph } 28812382Sralph 28912382Sralph /* 29012382Sralph * Enable queuing to the printer (allow lpr's). 29112382Sralph */ 29212382Sralph enable(argc, argv) 29312382Sralph char *argv[]; 29412382Sralph { 29512382Sralph register int c, status; 29612382Sralph register char *cp1, *cp2; 29712382Sralph char prbuf[100]; 29812382Sralph 29912382Sralph if (argc == 1) { 30012382Sralph printf("Usage: enable {all | printer ...}\n"); 30112382Sralph return; 30212382Sralph } 30312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 30412382Sralph printer = prbuf; 30512382Sralph while (getprent(line) > 0) { 30612382Sralph cp1 = prbuf; 30712382Sralph cp2 = line; 30812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 30912382Sralph *cp1++ = c; 31012382Sralph *cp1 = '\0'; 31112382Sralph enablepr(); 31212382Sralph } 31312382Sralph return; 31412382Sralph } 31512382Sralph while (--argc) { 31612382Sralph printer = *++argv; 31712382Sralph if ((status = pgetent(line, printer)) < 0) { 31812514Sralph printf("cannot open printer description file\n"); 31912382Sralph continue; 32012382Sralph } else if (status == 0) { 32112514Sralph printf("unknown printer %s\n", printer); 32212382Sralph continue; 32312382Sralph } 32412382Sralph enablepr(); 32512382Sralph } 32612382Sralph } 32712382Sralph 32812382Sralph enablepr() 32912382Sralph { 33012382Sralph struct stat stbuf; 33112382Sralph 33212382Sralph bp = pbuf; 33312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 33437968Sbostic SD = _PATH_DEFSPOOL; 33512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 33612382Sralph LO = DEFLOCK; 33712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 33812382Sralph printf("%s:\n", printer); 33912382Sralph 34012382Sralph /* 34112382Sralph * Turn off the group execute bit of the lock file to enable queuing. 34212382Sralph */ 34312382Sralph if (stat(line, &stbuf) >= 0) { 34412382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 34512514Sralph printf("\tcannot enable queuing\n"); 34612382Sralph else 34712382Sralph printf("\tqueuing enabled\n"); 34812382Sralph } 34912382Sralph } 35012382Sralph 35112382Sralph /* 35212382Sralph * Disable queuing. 35312382Sralph */ 35412382Sralph disable(argc, argv) 35512382Sralph char *argv[]; 35612382Sralph { 35712382Sralph register int c, status; 35812382Sralph register char *cp1, *cp2; 35912382Sralph char prbuf[100]; 36012382Sralph 36112382Sralph if (argc == 1) { 36212382Sralph printf("Usage: disable {all | printer ...}\n"); 36312382Sralph return; 36412382Sralph } 36512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 36612382Sralph printer = prbuf; 36712382Sralph while (getprent(line) > 0) { 36812382Sralph cp1 = prbuf; 36912382Sralph cp2 = line; 37012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 37112382Sralph *cp1++ = c; 37212382Sralph *cp1 = '\0'; 37312382Sralph disablepr(); 37412382Sralph } 37512382Sralph return; 37612382Sralph } 37712382Sralph while (--argc) { 37812382Sralph printer = *++argv; 37912382Sralph if ((status = pgetent(line, printer)) < 0) { 38012514Sralph printf("cannot open printer description file\n"); 38112382Sralph continue; 38212382Sralph } else if (status == 0) { 38312514Sralph printf("unknown printer %s\n", printer); 38412382Sralph continue; 38512382Sralph } 38612382Sralph disablepr(); 38712382Sralph } 38812382Sralph } 38912382Sralph 39012382Sralph disablepr() 39112382Sralph { 39212382Sralph register int fd; 39312382Sralph struct stat stbuf; 39412382Sralph 39512382Sralph bp = pbuf; 39612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 39737968Sbostic SD = _PATH_DEFSPOOL; 39812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 39912382Sralph LO = DEFLOCK; 40012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 40112382Sralph printf("%s:\n", printer); 40212382Sralph /* 40312382Sralph * Turn on the group execute bit of the lock file to disable queuing. 40412382Sralph */ 40512382Sralph if (stat(line, &stbuf) >= 0) { 40612382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 40712382Sralph printf("\tcannot disable queuing\n"); 40812382Sralph else 40912382Sralph printf("\tqueuing disabled\n"); 41012382Sralph } else if (errno == ENOENT) { 41113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 41212382Sralph printf("\tcannot create lock file\n"); 41312382Sralph else { 41412382Sralph (void) close(fd); 41512382Sralph printf("\tqueuing disabled\n"); 41612382Sralph } 41712382Sralph return; 41812382Sralph } else 41912382Sralph printf("\tcannot stat lock file\n"); 42012382Sralph } 42112382Sralph 42212382Sralph /* 42315907Sralph * Disable queuing and printing and put a message into the status file 42415907Sralph * (reason for being down). 42515907Sralph */ 42615907Sralph down(argc, argv) 42715907Sralph char *argv[]; 42815907Sralph { 42915907Sralph register int c, status; 43015907Sralph register char *cp1, *cp2; 43115907Sralph char prbuf[100]; 43215907Sralph 43315907Sralph if (argc == 1) { 43416204Sralph printf("Usage: down {all | printer} [message ...]\n"); 43515907Sralph return; 43615907Sralph } 43715907Sralph if (!strcmp(argv[1], "all")) { 43815907Sralph printer = prbuf; 43915907Sralph while (getprent(line) > 0) { 44015907Sralph cp1 = prbuf; 44115907Sralph cp2 = line; 44215907Sralph while ((c = *cp2++) && c != '|' && c != ':') 44315907Sralph *cp1++ = c; 44415907Sralph *cp1 = '\0'; 44515907Sralph putmsg(argc - 2, argv + 2); 44615907Sralph } 44715907Sralph return; 44815907Sralph } 44915907Sralph printer = argv[1]; 45015907Sralph if ((status = pgetent(line, printer)) < 0) { 45115907Sralph printf("cannot open printer description file\n"); 45215907Sralph return; 45315907Sralph } else if (status == 0) { 45415907Sralph printf("unknown printer %s\n", printer); 45515907Sralph return; 45615907Sralph } 45715907Sralph putmsg(argc - 2, argv + 2); 45815907Sralph } 45915907Sralph 46015907Sralph putmsg(argc, argv) 46115907Sralph char **argv; 46215907Sralph { 46315907Sralph register int fd; 46415907Sralph register char *cp1, *cp2; 46515907Sralph char buf[1024]; 46615907Sralph struct stat stbuf; 46715907Sralph 46815907Sralph bp = pbuf; 46915907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 47037968Sbostic SD = _PATH_DEFSPOOL; 47115907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 47215907Sralph LO = DEFLOCK; 47315907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 47415907Sralph ST = DEFSTAT; 47515907Sralph printf("%s:\n", printer); 47615907Sralph /* 47715907Sralph * Turn on the group execute bit of the lock file to disable queuing and 47815907Sralph * turn on the owner execute bit of the lock file to disable printing. 47915907Sralph */ 48015907Sralph (void) sprintf(line, "%s/%s", SD, LO); 48115907Sralph if (stat(line, &stbuf) >= 0) { 48215907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 48315907Sralph printf("\tcannot disable queuing\n"); 48415907Sralph else 48515907Sralph printf("\tprinter and queuing disabled\n"); 48615907Sralph } else if (errno == ENOENT) { 48715907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 48815907Sralph printf("\tcannot create lock file\n"); 48915907Sralph else { 49015907Sralph (void) close(fd); 49115907Sralph printf("\tprinter and queuing disabled\n"); 49215907Sralph } 49315907Sralph return; 49415907Sralph } else 49515907Sralph printf("\tcannot stat lock file\n"); 49615907Sralph /* 49715907Sralph * Write the message into the status file. 49815907Sralph */ 49915907Sralph (void) sprintf(line, "%s/%s", SD, ST); 50015907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 50115907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 50215907Sralph printf("\tcannot create status file\n"); 50315907Sralph return; 50415907Sralph } 50515907Sralph (void) ftruncate(fd, 0); 50616204Sralph if (argc <= 0) { 50716204Sralph (void) write(fd, "\n", 1); 50816204Sralph (void) close(fd); 50916204Sralph return; 51016204Sralph } 51115907Sralph cp1 = buf; 51215907Sralph while (--argc >= 0) { 51315907Sralph cp2 = *argv++; 51415907Sralph while (*cp1++ = *cp2++) 51515907Sralph ; 51615907Sralph cp1[-1] = ' '; 51715907Sralph } 51815907Sralph cp1[-1] = '\n'; 51915907Sralph *cp1 = '\0'; 52015907Sralph (void) write(fd, buf, strlen(buf)); 52115907Sralph (void) close(fd); 52215907Sralph } 52315907Sralph 52415907Sralph /* 52512382Sralph * Exit lpc 52612382Sralph */ 52712382Sralph quit(argc, argv) 52812382Sralph char *argv[]; 52912382Sralph { 53012382Sralph exit(0); 53112382Sralph } 53212382Sralph 53312382Sralph /* 53416755Sralph * Kill and restart the daemon. 53512382Sralph */ 53612382Sralph restart(argc, argv) 53712382Sralph char *argv[]; 53812382Sralph { 53912382Sralph register int c, status; 54012382Sralph register char *cp1, *cp2; 54112382Sralph char prbuf[100]; 54212382Sralph 54312382Sralph if (argc == 1) { 54412382Sralph printf("Usage: restart {all | printer ...}\n"); 54512382Sralph return; 54612382Sralph } 54712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 54812382Sralph printer = prbuf; 54912382Sralph while (getprent(line) > 0) { 55012382Sralph cp1 = prbuf; 55112382Sralph cp2 = line; 55212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 55312382Sralph *cp1++ = c; 55412382Sralph *cp1 = '\0'; 55516755Sralph abortpr(0); 55612382Sralph startpr(0); 55712382Sralph } 55812382Sralph return; 55912382Sralph } 56012382Sralph while (--argc) { 56112382Sralph printer = *++argv; 56212382Sralph if ((status = pgetent(line, printer)) < 0) { 56312514Sralph printf("cannot open printer description file\n"); 56412382Sralph continue; 56512382Sralph } else if (status == 0) { 56612514Sralph printf("unknown printer %s\n", printer); 56712382Sralph continue; 56812382Sralph } 56916755Sralph abortpr(0); 57012382Sralph startpr(0); 57112382Sralph } 57212382Sralph } 57312382Sralph 57412382Sralph /* 57512382Sralph * Enable printing on the specified printer and startup the daemon. 57612382Sralph */ 57712382Sralph start(argc, argv) 57812382Sralph char *argv[]; 57912382Sralph { 58012382Sralph register int c, status; 58112382Sralph register char *cp1, *cp2; 58212382Sralph char prbuf[100]; 58312382Sralph 58412382Sralph if (argc == 1) { 58512382Sralph printf("Usage: start {all | printer ...}\n"); 58612382Sralph return; 58712382Sralph } 58812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 58912382Sralph printer = prbuf; 59012382Sralph while (getprent(line) > 0) { 59112382Sralph cp1 = prbuf; 59212382Sralph cp2 = line; 59312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 59412382Sralph *cp1++ = c; 59512382Sralph *cp1 = '\0'; 59612382Sralph startpr(1); 59712382Sralph } 59812382Sralph return; 59912382Sralph } 60012382Sralph while (--argc) { 60112382Sralph printer = *++argv; 60212382Sralph if ((status = pgetent(line, printer)) < 0) { 60312514Sralph printf("cannot open printer description file\n"); 60412382Sralph continue; 60512382Sralph } else if (status == 0) { 60612514Sralph printf("unknown printer %s\n", printer); 60712382Sralph continue; 60812382Sralph } 60912382Sralph startpr(1); 61012382Sralph } 61112382Sralph } 61212382Sralph 61312382Sralph startpr(enable) 61412382Sralph { 61512382Sralph struct stat stbuf; 61612382Sralph 61712382Sralph bp = pbuf; 61812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 61937968Sbostic SD = _PATH_DEFSPOOL; 62012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 62112382Sralph LO = DEFLOCK; 62212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 62312382Sralph printf("%s:\n", printer); 62412382Sralph 62512382Sralph /* 62612382Sralph * Turn off the owner execute bit of the lock file to enable printing. 62712382Sralph */ 62812382Sralph if (enable && stat(line, &stbuf) >= 0) { 62916771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 63012382Sralph printf("\tcannot enable printing\n"); 63112382Sralph else 63212382Sralph printf("\tprinting enabled\n"); 63312382Sralph } 63413727Sroot if (!startdaemon(printer)) 63512382Sralph printf("\tcouldn't start daemon\n"); 63612382Sralph else 63712382Sralph printf("\tdaemon started\n"); 63812382Sralph } 63912382Sralph 64012382Sralph /* 64112382Sralph * Print the status of each queue listed or all the queues. 64212382Sralph */ 64312382Sralph status(argc, argv) 64412382Sralph char *argv[]; 64512382Sralph { 64612382Sralph register int c, status; 64712382Sralph register char *cp1, *cp2; 64812382Sralph char prbuf[100]; 64912382Sralph 65012382Sralph if (argc == 1) { 65112382Sralph printer = prbuf; 65212382Sralph while (getprent(line) > 0) { 65312382Sralph cp1 = prbuf; 65412382Sralph cp2 = line; 65512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 65612382Sralph *cp1++ = c; 65712382Sralph *cp1 = '\0'; 65812382Sralph prstat(); 65912382Sralph } 66012382Sralph return; 66112382Sralph } 66212382Sralph while (--argc) { 66312382Sralph printer = *++argv; 66412382Sralph if ((status = pgetent(line, printer)) < 0) { 66512514Sralph printf("cannot open printer description file\n"); 66612382Sralph continue; 66712382Sralph } else if (status == 0) { 66812514Sralph printf("unknown printer %s\n", printer); 66912382Sralph continue; 67012382Sralph } 67112382Sralph prstat(); 67212382Sralph } 67312382Sralph } 67412382Sralph 67512382Sralph /* 67612382Sralph * Print the status of the printer queue. 67712382Sralph */ 67812382Sralph prstat() 67912382Sralph { 68012382Sralph struct stat stbuf; 68112382Sralph register int fd, i; 68212382Sralph register struct direct *dp; 68312382Sralph DIR *dirp; 68412382Sralph 68512382Sralph bp = pbuf; 68612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 68737968Sbostic SD = _PATH_DEFSPOOL; 68812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 68912382Sralph LO = DEFLOCK; 69012382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 69112382Sralph ST = DEFSTAT; 69212382Sralph printf("%s:\n", printer); 69312382Sralph (void) sprintf(line, "%s/%s", SD, LO); 69412382Sralph if (stat(line, &stbuf) >= 0) { 69512382Sralph printf("\tqueuing is %s\n", 69612382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 69712382Sralph printf("\tprinting is %s\n", 69812382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 69912382Sralph } else { 70012382Sralph printf("\tqueuing is enabled\n"); 70112382Sralph printf("\tprinting is enabled\n"); 70212382Sralph } 70312382Sralph if ((dirp = opendir(SD)) == NULL) { 70412382Sralph printf("\tcannot examine spool directory\n"); 70512382Sralph return; 70612382Sralph } 70712382Sralph i = 0; 70812382Sralph while ((dp = readdir(dirp)) != NULL) { 70912382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 71012382Sralph i++; 71112382Sralph } 71212382Sralph closedir(dirp); 71312382Sralph if (i == 0) 71412382Sralph printf("\tno entries\n"); 71512382Sralph else if (i == 1) 71612382Sralph printf("\t1 entry in spool area\n"); 71712382Sralph else 71812382Sralph printf("\t%d entries in spool area\n", i); 71913146Ssam fd = open(line, O_RDONLY); 72013146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 72113168Sralph (void) close(fd); /* unlocks as well */ 72212382Sralph printf("\tno daemon present\n"); 72312382Sralph return; 72412382Sralph } 72512382Sralph (void) close(fd); 72612382Sralph putchar('\t'); 72712382Sralph (void) sprintf(line, "%s/%s", SD, ST); 72813146Ssam fd = open(line, O_RDONLY); 72913146Ssam if (fd >= 0) { 73013146Ssam (void) flock(fd, LOCK_SH); 73112382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 73212382Sralph (void) fwrite(line, 1, i, stdout); 73313168Sralph (void) close(fd); /* unlocks as well */ 73412382Sralph } 73512382Sralph } 73612382Sralph 73712382Sralph /* 73812382Sralph * Stop the specified daemon after completing the current job and disable 73912382Sralph * printing. 74012382Sralph */ 74112382Sralph stop(argc, argv) 74212382Sralph char *argv[]; 74312382Sralph { 74412382Sralph register int c, status; 74512382Sralph register char *cp1, *cp2; 74612382Sralph char prbuf[100]; 74712382Sralph 74812382Sralph if (argc == 1) { 74912382Sralph printf("Usage: stop {all | printer ...}\n"); 75012382Sralph return; 75112382Sralph } 75212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 75312382Sralph printer = prbuf; 75412382Sralph while (getprent(line) > 0) { 75512382Sralph cp1 = prbuf; 75612382Sralph cp2 = line; 75712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 75812382Sralph *cp1++ = c; 75912382Sralph *cp1 = '\0'; 76012382Sralph stoppr(); 76112382Sralph } 76212382Sralph return; 76312382Sralph } 76412382Sralph while (--argc) { 76512382Sralph printer = *++argv; 76612382Sralph if ((status = pgetent(line, printer)) < 0) { 76712514Sralph printf("cannot open printer description file\n"); 76812382Sralph continue; 76912382Sralph } else if (status == 0) { 77012514Sralph printf("unknown printer %s\n", printer); 77112382Sralph continue; 77212382Sralph } 77312382Sralph stoppr(); 77412382Sralph } 77512382Sralph } 77612382Sralph 77712382Sralph stoppr() 77812382Sralph { 77912382Sralph register int fd; 78012382Sralph struct stat stbuf; 78112382Sralph 78212382Sralph bp = pbuf; 78312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 78437968Sbostic SD = _PATH_DEFSPOOL; 78512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 78612382Sralph LO = DEFLOCK; 78712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 78812382Sralph printf("%s:\n", printer); 78912382Sralph 79012382Sralph /* 79112382Sralph * Turn on the owner execute bit of the lock file to disable printing. 79212382Sralph */ 79312382Sralph if (stat(line, &stbuf) >= 0) { 79412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 79512382Sralph printf("\tcannot disable printing\n"); 796*38735Stef else { 797*38735Stef upstat("printing disabled\n"); 79812382Sralph printf("\tprinting disabled\n"); 799*38735Stef } 80012382Sralph } else if (errno == ENOENT) { 80113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 80212382Sralph printf("\tcannot create lock file\n"); 80312382Sralph else { 80412382Sralph (void) close(fd); 805*38735Stef upstat("printing disabled\n"); 80612382Sralph printf("\tprinting disabled\n"); 80712382Sralph } 80812382Sralph } else 80912382Sralph printf("\tcannot stat lock file\n"); 81012382Sralph } 81113727Sroot 81215719Sralph struct queue **queue; 81315719Sralph int nitems; 81415719Sralph time_t mtime; 81515719Sralph 81613727Sroot /* 81713727Sroot * Put the specified jobs at the top of printer queue. 81813727Sroot */ 81913727Sroot topq(argc, argv) 82013727Sroot char *argv[]; 82113727Sroot { 82215719Sralph register int n, i; 82313727Sroot struct stat stbuf; 82413727Sroot register char *cfname; 82515719Sralph int status, changed; 82613727Sroot 82715719Sralph if (argc < 3) { 82813727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 82913727Sroot return; 83013727Sroot } 83113727Sroot 83213727Sroot --argc; 83313727Sroot printer = *++argv; 83413727Sroot status = pgetent(line, printer); 83513727Sroot if (status < 0) { 83613727Sroot printf("cannot open printer description file\n"); 83713727Sroot return; 83814151Sralph } else if (status == 0) { 83913727Sroot printf("%s: unknown printer\n", printer); 84013727Sroot return; 84113727Sroot } 84213727Sroot bp = pbuf; 84313727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 84437968Sbostic SD = _PATH_DEFSPOOL; 84513727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 84613727Sroot LO = DEFLOCK; 84713727Sroot printf("%s:\n", printer); 84813727Sroot 84913727Sroot if (chdir(SD) < 0) { 85013727Sroot printf("\tcannot chdir to %s\n", SD); 85113727Sroot return; 85213727Sroot } 85313727Sroot nitems = getq(&queue); 85415719Sralph if (nitems == 0) 85515719Sralph return; 85615719Sralph changed = 0; 85715719Sralph mtime = queue[0]->q_time; 85815719Sralph for (i = argc; --i; ) { 85915719Sralph if (doarg(argv[i]) == 0) { 86015719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 86113727Sroot continue; 86215719Sralph } else 86314151Sralph changed++; 86413727Sroot } 86515719Sralph for (i = 0; i < nitems; i++) 86615719Sralph free(queue[i]); 86715719Sralph free(queue); 86815719Sralph if (!changed) { 86915719Sralph printf("\tqueue order unchanged\n"); 87015719Sralph return; 87113727Sroot } 87213727Sroot /* 87313727Sroot * Turn on the public execute bit of the lock file to 87413727Sroot * get lpd to rebuild the queue after the current job. 87513727Sroot */ 87614151Sralph if (changed && stat(LO, &stbuf) >= 0) 87714151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 87813727Sroot } 87913727Sroot 88015719Sralph /* 88115719Sralph * Reposition the job by changing the modification time of 88215719Sralph * the control file. 88313727Sroot */ 88415719Sralph touch(q) 88515719Sralph struct queue *q; 88613727Sroot { 88715719Sralph struct timeval tvp[2]; 88813727Sroot 88915719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 89015719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 89115719Sralph return(utimes(q->q_name, tvp)); 89213727Sroot } 89313727Sroot 89413727Sroot /* 89513727Sroot * Checks if specified job name is in the printer's queue. 89613727Sroot * Returns: negative (-1) if argument name is not in the queue. 89713727Sroot */ 89815719Sralph doarg(job) 89913727Sroot char *job; 90013727Sroot { 90115719Sralph register struct queue **qq; 90215719Sralph register int jobnum, n; 90315719Sralph register char *cp, *machine; 90415719Sralph int cnt = 0; 90514151Sralph FILE *fp; 90613727Sroot 90715719Sralph /* 90815719Sralph * Look for a job item consisting of system name, colon, number 90915719Sralph * (example: ucbarpa:114) 91015719Sralph */ 91115719Sralph if ((cp = index(job, ':')) != NULL) { 91215719Sralph machine = job; 91315719Sralph *cp++ = '\0'; 91415719Sralph job = cp; 91515719Sralph } else 91615719Sralph machine = NULL; 91715719Sralph 91815719Sralph /* 91915719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 92015719Sralph */ 92113727Sroot if (isdigit(*job)) { 92213727Sroot jobnum = 0; 92313727Sroot do 92413727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 92513727Sroot while (isdigit(*job)); 92615719Sralph for (qq = queue + nitems; --qq >= queue; ) { 92713727Sroot n = 0; 92815719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 92914151Sralph n = n * 10 + (*cp++ - '0'); 93015719Sralph if (jobnum != n) 93115719Sralph continue; 93215719Sralph if (*job && strcmp(job, cp) != 0) 93315719Sralph continue; 93415719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 93515719Sralph continue; 93615719Sralph if (touch(*qq) == 0) { 93715719Sralph printf("\tmoved %s\n", (*qq)->q_name); 93815719Sralph cnt++; 93915719Sralph } 94013727Sroot } 94115719Sralph return(cnt); 94215719Sralph } 94315719Sralph /* 94415719Sralph * Process item consisting of owner's name (example: henry). 94515719Sralph */ 94615719Sralph for (qq = queue + nitems; --qq >= queue; ) { 94715719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 94813727Sroot continue; 94915719Sralph while (getline(fp) > 0) 95015719Sralph if (line[0] == 'P') 95115719Sralph break; 95215719Sralph (void) fclose(fp); 95315719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 95415719Sralph continue; 95515719Sralph if (touch(*qq) == 0) { 95615719Sralph printf("\tmoved %s\n", (*qq)->q_name); 95715719Sralph cnt++; 95813727Sroot } 95913727Sroot } 96015719Sralph return(cnt); 96113727Sroot } 96216755Sralph 96316755Sralph /* 96416755Sralph * Enable everything and start printer (undo `down'). 96516755Sralph */ 96616755Sralph up(argc, argv) 96716755Sralph char *argv[]; 96816755Sralph { 96916755Sralph register int c, status; 97016755Sralph register char *cp1, *cp2; 97116755Sralph char prbuf[100]; 97216755Sralph 97316755Sralph if (argc == 1) { 97416755Sralph printf("Usage: up {all | printer ...}\n"); 97516755Sralph return; 97616755Sralph } 97716755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 97816755Sralph printer = prbuf; 97916755Sralph while (getprent(line) > 0) { 98016755Sralph cp1 = prbuf; 98116755Sralph cp2 = line; 98216755Sralph while ((c = *cp2++) && c != '|' && c != ':') 98316755Sralph *cp1++ = c; 98416755Sralph *cp1 = '\0'; 98516755Sralph startpr(2); 98616755Sralph } 98716755Sralph return; 98816755Sralph } 98916755Sralph while (--argc) { 99016755Sralph printer = *++argv; 99116755Sralph if ((status = pgetent(line, printer)) < 0) { 99216755Sralph printf("cannot open printer description file\n"); 99316755Sralph continue; 99416755Sralph } else if (status == 0) { 99516755Sralph printf("unknown printer %s\n", printer); 99616755Sralph continue; 99716755Sralph } 99816755Sralph startpr(2); 99916755Sralph } 100016755Sralph } 1001