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*37968Sbostic static char sccsid[] = "@(#)cmds.c 5.5 (Berkeley) 05/11/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> 28*37968Sbostic #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) 77*37968Sbostic 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"); 9016755Sralph else 9116755Sralph printf("\tprinting disabled\n"); 9216755Sralph } else if (errno == ENOENT) { 9316755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 9416755Sralph printf("\tcannot create lock file\n"); 9516755Sralph else { 9616755Sralph (void) close(fd); 9716755Sralph printf("\tprinting disabled\n"); 9816755Sralph printf("\tno daemon to abort\n"); 9916755Sralph } 10016755Sralph return; 10116755Sralph } else { 10216755Sralph printf("\tcannot stat lock file\n"); 10316755Sralph return; 10412382Sralph } 10512382Sralph } 10612382Sralph /* 10712382Sralph * Kill the current daemon to stop printing now. 10812382Sralph */ 10912382Sralph if ((fp = fopen(line, "r")) == NULL) { 11012382Sralph printf("\tcannot open lock file\n"); 11112382Sralph return; 11212382Sralph } 11313146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 11413168Sralph (void) fclose(fp); /* unlocks as well */ 11512382Sralph printf("\tno daemon to abort\n"); 11612382Sralph return; 11712382Sralph } 11812382Sralph (void) fclose(fp); 11916755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 12012382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 12112382Sralph else 12212382Sralph printf("\tdaemon (pid %d) killed\n", pid); 12312382Sralph } 12412382Sralph 12512382Sralph /* 12612382Sralph * Remove all spool files and temporaries from the spooling area. 12712382Sralph */ 12812382Sralph clean(argc, argv) 12912382Sralph char *argv[]; 13012382Sralph { 13112382Sralph register int c, status; 13212382Sralph register char *cp1, *cp2; 13312382Sralph char prbuf[100]; 13412382Sralph 13512382Sralph if (argc == 1) { 13612382Sralph printf("Usage: clean {all | printer ...}\n"); 13712382Sralph return; 13812382Sralph } 13912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 14012382Sralph printer = prbuf; 14112382Sralph while (getprent(line) > 0) { 14212382Sralph cp1 = prbuf; 14312382Sralph cp2 = line; 14412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 14512382Sralph *cp1++ = c; 14612382Sralph *cp1 = '\0'; 14712382Sralph cleanpr(); 14812382Sralph } 14912382Sralph return; 15012382Sralph } 15112382Sralph while (--argc) { 15212382Sralph printer = *++argv; 15312382Sralph if ((status = pgetent(line, printer)) < 0) { 15412514Sralph printf("cannot open printer description file\n"); 15512382Sralph continue; 15612382Sralph } else if (status == 0) { 15712514Sralph printf("unknown printer %s\n", printer); 15812382Sralph continue; 15912382Sralph } 16012382Sralph cleanpr(); 16112382Sralph } 16212382Sralph } 16312382Sralph 16415719Sralph select(d) 16515719Sralph struct direct *d; 16615719Sralph { 16715719Sralph int c = d->d_name[0]; 16815719Sralph 16915719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 17015719Sralph return(1); 17115719Sralph return(0); 17215719Sralph } 17315719Sralph 17415719Sralph /* 17515719Sralph * Comparison routine for scandir. Sort by job number and machine, then 17615719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 17715719Sralph */ 17815719Sralph sortq(d1, d2) 17915719Sralph struct direct **d1, **d2; 18015719Sralph { 18115719Sralph int c1, c2; 18215719Sralph 18315719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 18415719Sralph return(c1); 18515719Sralph c1 = (*d1)->d_name[0]; 18615719Sralph c2 = (*d2)->d_name[0]; 18715719Sralph if (c1 == c2) 18815719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 18915719Sralph if (c1 == 'c') 19015719Sralph return(-1); 19115719Sralph if (c1 == 'd' || c2 == 'c') 19215719Sralph return(1); 19315719Sralph return(-1); 19415719Sralph } 19515719Sralph 19615719Sralph /* 19715719Sralph * Remove incomplete jobs from spooling area. 19815719Sralph */ 19912382Sralph cleanpr() 20012382Sralph { 20115719Sralph register int i, n; 20215719Sralph register char *cp, *cp1, *lp; 20315719Sralph struct direct **queue; 20415719Sralph int nitems; 20512382Sralph 20612382Sralph bp = pbuf; 20712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 208*37968Sbostic SD = _PATH_DEFSPOOL; 20912382Sralph printf("%s:\n", printer); 21012382Sralph 21115719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 21215719Sralph ; 21315719Sralph lp[-1] = '/'; 21415719Sralph 21515719Sralph nitems = scandir(SD, &queue, select, sortq); 21615719Sralph if (nitems < 0) { 21712382Sralph printf("\tcannot examine spool directory\n"); 21812382Sralph return; 21912382Sralph } 22015719Sralph if (nitems == 0) 22115719Sralph return; 22215719Sralph i = 0; 22315719Sralph do { 22415719Sralph cp = queue[i]->d_name; 22515719Sralph if (*cp == 'c') { 22615719Sralph n = 0; 22715719Sralph while (i + 1 < nitems) { 22815719Sralph cp1 = queue[i + 1]->d_name; 22915719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 23015719Sralph break; 23115719Sralph i++; 23215719Sralph n++; 23315719Sralph } 23415719Sralph if (n == 0) { 23515719Sralph strcpy(lp, cp); 23615719Sralph unlinkf(line); 23715719Sralph } 23815719Sralph } else { 23915719Sralph /* 24015719Sralph * Must be a df with no cf (otherwise, it would have 24115719Sralph * been skipped above) or a tf file (which can always 24215719Sralph * be removed). 24315719Sralph */ 24415719Sralph strcpy(lp, cp); 24515719Sralph unlinkf(line); 24612382Sralph } 24715719Sralph } while (++i < nitems); 24812382Sralph } 24915719Sralph 25015719Sralph unlinkf(name) 25115719Sralph char *name; 25215719Sralph { 25315719Sralph if (unlink(name) < 0) 25415719Sralph printf("\tcannot remove %s\n", name); 25515719Sralph else 25615719Sralph printf("\tremoved %s\n", name); 25715719Sralph } 25812382Sralph 25912382Sralph /* 26012382Sralph * Enable queuing to the printer (allow lpr's). 26112382Sralph */ 26212382Sralph enable(argc, argv) 26312382Sralph char *argv[]; 26412382Sralph { 26512382Sralph register int c, status; 26612382Sralph register char *cp1, *cp2; 26712382Sralph char prbuf[100]; 26812382Sralph 26912382Sralph if (argc == 1) { 27012382Sralph printf("Usage: enable {all | printer ...}\n"); 27112382Sralph return; 27212382Sralph } 27312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 27412382Sralph printer = prbuf; 27512382Sralph while (getprent(line) > 0) { 27612382Sralph cp1 = prbuf; 27712382Sralph cp2 = line; 27812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 27912382Sralph *cp1++ = c; 28012382Sralph *cp1 = '\0'; 28112382Sralph enablepr(); 28212382Sralph } 28312382Sralph return; 28412382Sralph } 28512382Sralph while (--argc) { 28612382Sralph printer = *++argv; 28712382Sralph if ((status = pgetent(line, printer)) < 0) { 28812514Sralph printf("cannot open printer description file\n"); 28912382Sralph continue; 29012382Sralph } else if (status == 0) { 29112514Sralph printf("unknown printer %s\n", printer); 29212382Sralph continue; 29312382Sralph } 29412382Sralph enablepr(); 29512382Sralph } 29612382Sralph } 29712382Sralph 29812382Sralph enablepr() 29912382Sralph { 30012382Sralph struct stat stbuf; 30112382Sralph 30212382Sralph bp = pbuf; 30312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 304*37968Sbostic SD = _PATH_DEFSPOOL; 30512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 30612382Sralph LO = DEFLOCK; 30712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 30812382Sralph printf("%s:\n", printer); 30912382Sralph 31012382Sralph /* 31112382Sralph * Turn off the group execute bit of the lock file to enable queuing. 31212382Sralph */ 31312382Sralph if (stat(line, &stbuf) >= 0) { 31412382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 31512514Sralph printf("\tcannot enable queuing\n"); 31612382Sralph else 31712382Sralph printf("\tqueuing enabled\n"); 31812382Sralph } 31912382Sralph } 32012382Sralph 32112382Sralph /* 32212382Sralph * Disable queuing. 32312382Sralph */ 32412382Sralph disable(argc, argv) 32512382Sralph char *argv[]; 32612382Sralph { 32712382Sralph register int c, status; 32812382Sralph register char *cp1, *cp2; 32912382Sralph char prbuf[100]; 33012382Sralph 33112382Sralph if (argc == 1) { 33212382Sralph printf("Usage: disable {all | printer ...}\n"); 33312382Sralph return; 33412382Sralph } 33512382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 33612382Sralph printer = prbuf; 33712382Sralph while (getprent(line) > 0) { 33812382Sralph cp1 = prbuf; 33912382Sralph cp2 = line; 34012382Sralph while ((c = *cp2++) && c != '|' && c != ':') 34112382Sralph *cp1++ = c; 34212382Sralph *cp1 = '\0'; 34312382Sralph disablepr(); 34412382Sralph } 34512382Sralph return; 34612382Sralph } 34712382Sralph while (--argc) { 34812382Sralph printer = *++argv; 34912382Sralph if ((status = pgetent(line, printer)) < 0) { 35012514Sralph printf("cannot open printer description file\n"); 35112382Sralph continue; 35212382Sralph } else if (status == 0) { 35312514Sralph printf("unknown printer %s\n", printer); 35412382Sralph continue; 35512382Sralph } 35612382Sralph disablepr(); 35712382Sralph } 35812382Sralph } 35912382Sralph 36012382Sralph disablepr() 36112382Sralph { 36212382Sralph register int fd; 36312382Sralph struct stat stbuf; 36412382Sralph 36512382Sralph bp = pbuf; 36612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 367*37968Sbostic SD = _PATH_DEFSPOOL; 36812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 36912382Sralph LO = DEFLOCK; 37012382Sralph (void) sprintf(line, "%s/%s", SD, LO); 37112382Sralph printf("%s:\n", printer); 37212382Sralph /* 37312382Sralph * Turn on the group execute bit of the lock file to disable queuing. 37412382Sralph */ 37512382Sralph if (stat(line, &stbuf) >= 0) { 37612382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 37712382Sralph printf("\tcannot disable queuing\n"); 37812382Sralph else 37912382Sralph printf("\tqueuing disabled\n"); 38012382Sralph } else if (errno == ENOENT) { 38113146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 38212382Sralph printf("\tcannot create lock file\n"); 38312382Sralph else { 38412382Sralph (void) close(fd); 38512382Sralph printf("\tqueuing disabled\n"); 38612382Sralph } 38712382Sralph return; 38812382Sralph } else 38912382Sralph printf("\tcannot stat lock file\n"); 39012382Sralph } 39112382Sralph 39212382Sralph /* 39315907Sralph * Disable queuing and printing and put a message into the status file 39415907Sralph * (reason for being down). 39515907Sralph */ 39615907Sralph down(argc, argv) 39715907Sralph char *argv[]; 39815907Sralph { 39915907Sralph register int c, status; 40015907Sralph register char *cp1, *cp2; 40115907Sralph char prbuf[100]; 40215907Sralph 40315907Sralph if (argc == 1) { 40416204Sralph printf("Usage: down {all | printer} [message ...]\n"); 40515907Sralph return; 40615907Sralph } 40715907Sralph if (!strcmp(argv[1], "all")) { 40815907Sralph printer = prbuf; 40915907Sralph while (getprent(line) > 0) { 41015907Sralph cp1 = prbuf; 41115907Sralph cp2 = line; 41215907Sralph while ((c = *cp2++) && c != '|' && c != ':') 41315907Sralph *cp1++ = c; 41415907Sralph *cp1 = '\0'; 41515907Sralph putmsg(argc - 2, argv + 2); 41615907Sralph } 41715907Sralph return; 41815907Sralph } 41915907Sralph printer = argv[1]; 42015907Sralph if ((status = pgetent(line, printer)) < 0) { 42115907Sralph printf("cannot open printer description file\n"); 42215907Sralph return; 42315907Sralph } else if (status == 0) { 42415907Sralph printf("unknown printer %s\n", printer); 42515907Sralph return; 42615907Sralph } 42715907Sralph putmsg(argc - 2, argv + 2); 42815907Sralph } 42915907Sralph 43015907Sralph putmsg(argc, argv) 43115907Sralph char **argv; 43215907Sralph { 43315907Sralph register int fd; 43415907Sralph register char *cp1, *cp2; 43515907Sralph char buf[1024]; 43615907Sralph struct stat stbuf; 43715907Sralph 43815907Sralph bp = pbuf; 43915907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 440*37968Sbostic SD = _PATH_DEFSPOOL; 44115907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 44215907Sralph LO = DEFLOCK; 44315907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 44415907Sralph ST = DEFSTAT; 44515907Sralph printf("%s:\n", printer); 44615907Sralph /* 44715907Sralph * Turn on the group execute bit of the lock file to disable queuing and 44815907Sralph * turn on the owner execute bit of the lock file to disable printing. 44915907Sralph */ 45015907Sralph (void) sprintf(line, "%s/%s", SD, LO); 45115907Sralph if (stat(line, &stbuf) >= 0) { 45215907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 45315907Sralph printf("\tcannot disable queuing\n"); 45415907Sralph else 45515907Sralph printf("\tprinter and queuing disabled\n"); 45615907Sralph } else if (errno == ENOENT) { 45715907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 45815907Sralph printf("\tcannot create lock file\n"); 45915907Sralph else { 46015907Sralph (void) close(fd); 46115907Sralph printf("\tprinter and queuing disabled\n"); 46215907Sralph } 46315907Sralph return; 46415907Sralph } else 46515907Sralph printf("\tcannot stat lock file\n"); 46615907Sralph /* 46715907Sralph * Write the message into the status file. 46815907Sralph */ 46915907Sralph (void) sprintf(line, "%s/%s", SD, ST); 47015907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 47115907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 47215907Sralph printf("\tcannot create status file\n"); 47315907Sralph return; 47415907Sralph } 47515907Sralph (void) ftruncate(fd, 0); 47616204Sralph if (argc <= 0) { 47716204Sralph (void) write(fd, "\n", 1); 47816204Sralph (void) close(fd); 47916204Sralph return; 48016204Sralph } 48115907Sralph cp1 = buf; 48215907Sralph while (--argc >= 0) { 48315907Sralph cp2 = *argv++; 48415907Sralph while (*cp1++ = *cp2++) 48515907Sralph ; 48615907Sralph cp1[-1] = ' '; 48715907Sralph } 48815907Sralph cp1[-1] = '\n'; 48915907Sralph *cp1 = '\0'; 49015907Sralph (void) write(fd, buf, strlen(buf)); 49115907Sralph (void) close(fd); 49215907Sralph } 49315907Sralph 49415907Sralph /* 49512382Sralph * Exit lpc 49612382Sralph */ 49712382Sralph quit(argc, argv) 49812382Sralph char *argv[]; 49912382Sralph { 50012382Sralph exit(0); 50112382Sralph } 50212382Sralph 50312382Sralph /* 50416755Sralph * Kill and restart the daemon. 50512382Sralph */ 50612382Sralph restart(argc, argv) 50712382Sralph char *argv[]; 50812382Sralph { 50912382Sralph register int c, status; 51012382Sralph register char *cp1, *cp2; 51112382Sralph char prbuf[100]; 51212382Sralph 51312382Sralph if (argc == 1) { 51412382Sralph printf("Usage: restart {all | printer ...}\n"); 51512382Sralph return; 51612382Sralph } 51712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 51812382Sralph printer = prbuf; 51912382Sralph while (getprent(line) > 0) { 52012382Sralph cp1 = prbuf; 52112382Sralph cp2 = line; 52212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 52312382Sralph *cp1++ = c; 52412382Sralph *cp1 = '\0'; 52516755Sralph abortpr(0); 52612382Sralph startpr(0); 52712382Sralph } 52812382Sralph return; 52912382Sralph } 53012382Sralph while (--argc) { 53112382Sralph printer = *++argv; 53212382Sralph if ((status = pgetent(line, printer)) < 0) { 53312514Sralph printf("cannot open printer description file\n"); 53412382Sralph continue; 53512382Sralph } else if (status == 0) { 53612514Sralph printf("unknown printer %s\n", printer); 53712382Sralph continue; 53812382Sralph } 53916755Sralph abortpr(0); 54012382Sralph startpr(0); 54112382Sralph } 54212382Sralph } 54312382Sralph 54412382Sralph /* 54512382Sralph * Enable printing on the specified printer and startup the daemon. 54612382Sralph */ 54712382Sralph start(argc, argv) 54812382Sralph char *argv[]; 54912382Sralph { 55012382Sralph register int c, status; 55112382Sralph register char *cp1, *cp2; 55212382Sralph char prbuf[100]; 55312382Sralph 55412382Sralph if (argc == 1) { 55512382Sralph printf("Usage: start {all | printer ...}\n"); 55612382Sralph return; 55712382Sralph } 55812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 55912382Sralph printer = prbuf; 56012382Sralph while (getprent(line) > 0) { 56112382Sralph cp1 = prbuf; 56212382Sralph cp2 = line; 56312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 56412382Sralph *cp1++ = c; 56512382Sralph *cp1 = '\0'; 56612382Sralph startpr(1); 56712382Sralph } 56812382Sralph return; 56912382Sralph } 57012382Sralph while (--argc) { 57112382Sralph printer = *++argv; 57212382Sralph if ((status = pgetent(line, printer)) < 0) { 57312514Sralph printf("cannot open printer description file\n"); 57412382Sralph continue; 57512382Sralph } else if (status == 0) { 57612514Sralph printf("unknown printer %s\n", printer); 57712382Sralph continue; 57812382Sralph } 57912382Sralph startpr(1); 58012382Sralph } 58112382Sralph } 58212382Sralph 58312382Sralph startpr(enable) 58412382Sralph { 58512382Sralph struct stat stbuf; 58612382Sralph 58712382Sralph bp = pbuf; 58812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 589*37968Sbostic SD = _PATH_DEFSPOOL; 59012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 59112382Sralph LO = DEFLOCK; 59212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 59312382Sralph printf("%s:\n", printer); 59412382Sralph 59512382Sralph /* 59612382Sralph * Turn off the owner execute bit of the lock file to enable printing. 59712382Sralph */ 59812382Sralph if (enable && stat(line, &stbuf) >= 0) { 59916771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 60012382Sralph printf("\tcannot enable printing\n"); 60112382Sralph else 60212382Sralph printf("\tprinting enabled\n"); 60312382Sralph } 60413727Sroot if (!startdaemon(printer)) 60512382Sralph printf("\tcouldn't start daemon\n"); 60612382Sralph else 60712382Sralph printf("\tdaemon started\n"); 60812382Sralph } 60912382Sralph 61012382Sralph /* 61112382Sralph * Print the status of each queue listed or all the queues. 61212382Sralph */ 61312382Sralph status(argc, argv) 61412382Sralph char *argv[]; 61512382Sralph { 61612382Sralph register int c, status; 61712382Sralph register char *cp1, *cp2; 61812382Sralph char prbuf[100]; 61912382Sralph 62012382Sralph if (argc == 1) { 62112382Sralph printer = prbuf; 62212382Sralph while (getprent(line) > 0) { 62312382Sralph cp1 = prbuf; 62412382Sralph cp2 = line; 62512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 62612382Sralph *cp1++ = c; 62712382Sralph *cp1 = '\0'; 62812382Sralph prstat(); 62912382Sralph } 63012382Sralph return; 63112382Sralph } 63212382Sralph while (--argc) { 63312382Sralph printer = *++argv; 63412382Sralph if ((status = pgetent(line, printer)) < 0) { 63512514Sralph printf("cannot open printer description file\n"); 63612382Sralph continue; 63712382Sralph } else if (status == 0) { 63812514Sralph printf("unknown printer %s\n", printer); 63912382Sralph continue; 64012382Sralph } 64112382Sralph prstat(); 64212382Sralph } 64312382Sralph } 64412382Sralph 64512382Sralph /* 64612382Sralph * Print the status of the printer queue. 64712382Sralph */ 64812382Sralph prstat() 64912382Sralph { 65012382Sralph struct stat stbuf; 65112382Sralph register int fd, i; 65212382Sralph register struct direct *dp; 65312382Sralph DIR *dirp; 65412382Sralph 65512382Sralph bp = pbuf; 65612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 657*37968Sbostic SD = _PATH_DEFSPOOL; 65812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 65912382Sralph LO = DEFLOCK; 66012382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 66112382Sralph ST = DEFSTAT; 66212382Sralph printf("%s:\n", printer); 66312382Sralph (void) sprintf(line, "%s/%s", SD, LO); 66412382Sralph if (stat(line, &stbuf) >= 0) { 66512382Sralph printf("\tqueuing is %s\n", 66612382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 66712382Sralph printf("\tprinting is %s\n", 66812382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 66912382Sralph } else { 67012382Sralph printf("\tqueuing is enabled\n"); 67112382Sralph printf("\tprinting is enabled\n"); 67212382Sralph } 67312382Sralph if ((dirp = opendir(SD)) == NULL) { 67412382Sralph printf("\tcannot examine spool directory\n"); 67512382Sralph return; 67612382Sralph } 67712382Sralph i = 0; 67812382Sralph while ((dp = readdir(dirp)) != NULL) { 67912382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 68012382Sralph i++; 68112382Sralph } 68212382Sralph closedir(dirp); 68312382Sralph if (i == 0) 68412382Sralph printf("\tno entries\n"); 68512382Sralph else if (i == 1) 68612382Sralph printf("\t1 entry in spool area\n"); 68712382Sralph else 68812382Sralph printf("\t%d entries in spool area\n", i); 68913146Ssam fd = open(line, O_RDONLY); 69013146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 69113168Sralph (void) close(fd); /* unlocks as well */ 69212382Sralph printf("\tno daemon present\n"); 69312382Sralph return; 69412382Sralph } 69512382Sralph (void) close(fd); 69612382Sralph putchar('\t'); 69712382Sralph (void) sprintf(line, "%s/%s", SD, ST); 69813146Ssam fd = open(line, O_RDONLY); 69913146Ssam if (fd >= 0) { 70013146Ssam (void) flock(fd, LOCK_SH); 70112382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 70212382Sralph (void) fwrite(line, 1, i, stdout); 70313168Sralph (void) close(fd); /* unlocks as well */ 70412382Sralph } 70512382Sralph } 70612382Sralph 70712382Sralph /* 70812382Sralph * Stop the specified daemon after completing the current job and disable 70912382Sralph * printing. 71012382Sralph */ 71112382Sralph stop(argc, argv) 71212382Sralph char *argv[]; 71312382Sralph { 71412382Sralph register int c, status; 71512382Sralph register char *cp1, *cp2; 71612382Sralph char prbuf[100]; 71712382Sralph 71812382Sralph if (argc == 1) { 71912382Sralph printf("Usage: stop {all | printer ...}\n"); 72012382Sralph return; 72112382Sralph } 72212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 72312382Sralph printer = prbuf; 72412382Sralph while (getprent(line) > 0) { 72512382Sralph cp1 = prbuf; 72612382Sralph cp2 = line; 72712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 72812382Sralph *cp1++ = c; 72912382Sralph *cp1 = '\0'; 73012382Sralph stoppr(); 73112382Sralph } 73212382Sralph return; 73312382Sralph } 73412382Sralph while (--argc) { 73512382Sralph printer = *++argv; 73612382Sralph if ((status = pgetent(line, printer)) < 0) { 73712514Sralph printf("cannot open printer description file\n"); 73812382Sralph continue; 73912382Sralph } else if (status == 0) { 74012514Sralph printf("unknown printer %s\n", printer); 74112382Sralph continue; 74212382Sralph } 74312382Sralph stoppr(); 74412382Sralph } 74512382Sralph } 74612382Sralph 74712382Sralph stoppr() 74812382Sralph { 74912382Sralph register int fd; 75012382Sralph struct stat stbuf; 75112382Sralph 75212382Sralph bp = pbuf; 75312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 754*37968Sbostic SD = _PATH_DEFSPOOL; 75512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 75612382Sralph LO = DEFLOCK; 75712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 75812382Sralph printf("%s:\n", printer); 75912382Sralph 76012382Sralph /* 76112382Sralph * Turn on the owner execute bit of the lock file to disable printing. 76212382Sralph */ 76312382Sralph if (stat(line, &stbuf) >= 0) { 76412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 76512382Sralph printf("\tcannot disable printing\n"); 76612382Sralph else 76712382Sralph printf("\tprinting disabled\n"); 76812382Sralph } else if (errno == ENOENT) { 76913146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 77012382Sralph printf("\tcannot create lock file\n"); 77112382Sralph else { 77212382Sralph (void) close(fd); 77312382Sralph printf("\tprinting disabled\n"); 77412382Sralph } 77512382Sralph } else 77612382Sralph printf("\tcannot stat lock file\n"); 77712382Sralph } 77813727Sroot 77915719Sralph struct queue **queue; 78015719Sralph int nitems; 78115719Sralph time_t mtime; 78215719Sralph 78313727Sroot /* 78413727Sroot * Put the specified jobs at the top of printer queue. 78513727Sroot */ 78613727Sroot topq(argc, argv) 78713727Sroot char *argv[]; 78813727Sroot { 78915719Sralph register int n, i; 79013727Sroot struct stat stbuf; 79113727Sroot register char *cfname; 79215719Sralph int status, changed; 79313727Sroot 79415719Sralph if (argc < 3) { 79513727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 79613727Sroot return; 79713727Sroot } 79813727Sroot 79913727Sroot --argc; 80013727Sroot printer = *++argv; 80113727Sroot status = pgetent(line, printer); 80213727Sroot if (status < 0) { 80313727Sroot printf("cannot open printer description file\n"); 80413727Sroot return; 80514151Sralph } else if (status == 0) { 80613727Sroot printf("%s: unknown printer\n", printer); 80713727Sroot return; 80813727Sroot } 80913727Sroot bp = pbuf; 81013727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 811*37968Sbostic SD = _PATH_DEFSPOOL; 81213727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 81313727Sroot LO = DEFLOCK; 81413727Sroot printf("%s:\n", printer); 81513727Sroot 81613727Sroot if (chdir(SD) < 0) { 81713727Sroot printf("\tcannot chdir to %s\n", SD); 81813727Sroot return; 81913727Sroot } 82013727Sroot nitems = getq(&queue); 82115719Sralph if (nitems == 0) 82215719Sralph return; 82315719Sralph changed = 0; 82415719Sralph mtime = queue[0]->q_time; 82515719Sralph for (i = argc; --i; ) { 82615719Sralph if (doarg(argv[i]) == 0) { 82715719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 82813727Sroot continue; 82915719Sralph } else 83014151Sralph changed++; 83113727Sroot } 83215719Sralph for (i = 0; i < nitems; i++) 83315719Sralph free(queue[i]); 83415719Sralph free(queue); 83515719Sralph if (!changed) { 83615719Sralph printf("\tqueue order unchanged\n"); 83715719Sralph return; 83813727Sroot } 83913727Sroot /* 84013727Sroot * Turn on the public execute bit of the lock file to 84113727Sroot * get lpd to rebuild the queue after the current job. 84213727Sroot */ 84314151Sralph if (changed && stat(LO, &stbuf) >= 0) 84414151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 84513727Sroot } 84613727Sroot 84715719Sralph /* 84815719Sralph * Reposition the job by changing the modification time of 84915719Sralph * the control file. 85013727Sroot */ 85115719Sralph touch(q) 85215719Sralph struct queue *q; 85313727Sroot { 85415719Sralph struct timeval tvp[2]; 85513727Sroot 85615719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 85715719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 85815719Sralph return(utimes(q->q_name, tvp)); 85913727Sroot } 86013727Sroot 86113727Sroot /* 86213727Sroot * Checks if specified job name is in the printer's queue. 86313727Sroot * Returns: negative (-1) if argument name is not in the queue. 86413727Sroot */ 86515719Sralph doarg(job) 86613727Sroot char *job; 86713727Sroot { 86815719Sralph register struct queue **qq; 86915719Sralph register int jobnum, n; 87015719Sralph register char *cp, *machine; 87115719Sralph int cnt = 0; 87214151Sralph FILE *fp; 87313727Sroot 87415719Sralph /* 87515719Sralph * Look for a job item consisting of system name, colon, number 87615719Sralph * (example: ucbarpa:114) 87715719Sralph */ 87815719Sralph if ((cp = index(job, ':')) != NULL) { 87915719Sralph machine = job; 88015719Sralph *cp++ = '\0'; 88115719Sralph job = cp; 88215719Sralph } else 88315719Sralph machine = NULL; 88415719Sralph 88515719Sralph /* 88615719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 88715719Sralph */ 88813727Sroot if (isdigit(*job)) { 88913727Sroot jobnum = 0; 89013727Sroot do 89113727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 89213727Sroot while (isdigit(*job)); 89315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 89413727Sroot n = 0; 89515719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 89614151Sralph n = n * 10 + (*cp++ - '0'); 89715719Sralph if (jobnum != n) 89815719Sralph continue; 89915719Sralph if (*job && strcmp(job, cp) != 0) 90015719Sralph continue; 90115719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 90215719Sralph continue; 90315719Sralph if (touch(*qq) == 0) { 90415719Sralph printf("\tmoved %s\n", (*qq)->q_name); 90515719Sralph cnt++; 90615719Sralph } 90713727Sroot } 90815719Sralph return(cnt); 90915719Sralph } 91015719Sralph /* 91115719Sralph * Process item consisting of owner's name (example: henry). 91215719Sralph */ 91315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 91415719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 91513727Sroot continue; 91615719Sralph while (getline(fp) > 0) 91715719Sralph if (line[0] == 'P') 91815719Sralph break; 91915719Sralph (void) fclose(fp); 92015719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 92115719Sralph continue; 92215719Sralph if (touch(*qq) == 0) { 92315719Sralph printf("\tmoved %s\n", (*qq)->q_name); 92415719Sralph cnt++; 92513727Sroot } 92613727Sroot } 92715719Sralph return(cnt); 92813727Sroot } 92916755Sralph 93016755Sralph /* 93116755Sralph * Enable everything and start printer (undo `down'). 93216755Sralph */ 93316755Sralph up(argc, argv) 93416755Sralph char *argv[]; 93516755Sralph { 93616755Sralph register int c, status; 93716755Sralph register char *cp1, *cp2; 93816755Sralph char prbuf[100]; 93916755Sralph 94016755Sralph if (argc == 1) { 94116755Sralph printf("Usage: up {all | printer ...}\n"); 94216755Sralph return; 94316755Sralph } 94416755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 94516755Sralph printer = prbuf; 94616755Sralph while (getprent(line) > 0) { 94716755Sralph cp1 = prbuf; 94816755Sralph cp2 = line; 94916755Sralph while ((c = *cp2++) && c != '|' && c != ':') 95016755Sralph *cp1++ = c; 95116755Sralph *cp1 = '\0'; 95216755Sralph startpr(2); 95316755Sralph } 95416755Sralph return; 95516755Sralph } 95616755Sralph while (--argc) { 95716755Sralph printer = *++argv; 95816755Sralph if ((status = pgetent(line, printer)) < 0) { 95916755Sralph printf("cannot open printer description file\n"); 96016755Sralph continue; 96116755Sralph } else if (status == 0) { 96216755Sralph printf("unknown printer %s\n", printer); 96316755Sralph continue; 96416755Sralph } 96516755Sralph startpr(2); 96616755Sralph } 96716755Sralph } 968