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 6*34936Sbostic * provided that the above copyright notice and this paragraph are 7*34936Sbostic * duplicated in all such forms and that any documentation, 8*34936Sbostic * advertising materials, and other materials related to such 9*34936Sbostic * distribution and use acknowledge that the software was developed 10*34936Sbostic * by the University of California, Berkeley. The name of the 11*34936Sbostic * University may not be used to endorse or promote products derived 12*34936Sbostic * from this software without specific prior written permission. 13*34936Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34936Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34936Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622424Sdist */ 1722424Sdist 1812382Sralph #ifndef lint 19*34936Sbostic static char sccsid[] = "@(#)cmds.c 5.4 (Berkeley) 06/30/88"; 2034203Sbostic #endif /* not lint */ 2112382Sralph 2212382Sralph /* 2315719Sralph * lpc -- line printer control program -- commands: 2412382Sralph */ 2512382Sralph 2612382Sralph #include "lp.h" 2715719Sralph #include <sys/time.h> 2812382Sralph 2912382Sralph /* 3012382Sralph * kill an existing daemon and disable printing. 3112382Sralph */ 3212382Sralph abort(argc, argv) 3312382Sralph char *argv[]; 3412382Sralph { 3512382Sralph register int c, status; 3612382Sralph register char *cp1, *cp2; 3712382Sralph char prbuf[100]; 3812382Sralph 3912382Sralph if (argc == 1) { 4012382Sralph printf("Usage: abort {all | printer ...}\n"); 4112382Sralph return; 4212382Sralph } 4312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 4412382Sralph printer = prbuf; 4512382Sralph while (getprent(line) > 0) { 4612382Sralph cp1 = prbuf; 4712382Sralph cp2 = line; 4812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 4912382Sralph *cp1++ = c; 5012382Sralph *cp1 = '\0'; 5116755Sralph abortpr(1); 5212382Sralph } 5312382Sralph return; 5412382Sralph } 5512382Sralph while (--argc) { 5612382Sralph printer = *++argv; 5712382Sralph if ((status = pgetent(line, printer)) < 0) { 5812514Sralph printf("cannot open printer description file\n"); 5912382Sralph continue; 6012382Sralph } else if (status == 0) { 6112514Sralph printf("unknown printer %s\n", printer); 6212382Sralph continue; 6312382Sralph } 6416755Sralph abortpr(1); 6512382Sralph } 6612382Sralph } 6712382Sralph 6816755Sralph abortpr(dis) 6912382Sralph { 7012382Sralph register FILE *fp; 7112382Sralph struct stat stbuf; 7212382Sralph int pid, fd; 7312382Sralph 7412382Sralph bp = pbuf; 7512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 7612382Sralph SD = DEFSPOOL; 7712382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 7812382Sralph LO = DEFLOCK; 7912382Sralph (void) sprintf(line, "%s/%s", SD, LO); 8012382Sralph printf("%s:\n", printer); 8112382Sralph 8212382Sralph /* 8312382Sralph * Turn on the owner execute bit of the lock file to disable printing. 8412382Sralph */ 8516755Sralph if (dis) { 8616755Sralph if (stat(line, &stbuf) >= 0) { 8716755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 8816755Sralph printf("\tcannot disable printing\n"); 8916755Sralph else 9016755Sralph printf("\tprinting disabled\n"); 9116755Sralph } else if (errno == ENOENT) { 9216755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 9316755Sralph printf("\tcannot create lock file\n"); 9416755Sralph else { 9516755Sralph (void) close(fd); 9616755Sralph printf("\tprinting disabled\n"); 9716755Sralph printf("\tno daemon to abort\n"); 9816755Sralph } 9916755Sralph return; 10016755Sralph } else { 10116755Sralph printf("\tcannot stat lock file\n"); 10216755Sralph return; 10312382Sralph } 10412382Sralph } 10512382Sralph /* 10612382Sralph * Kill the current daemon to stop printing now. 10712382Sralph */ 10812382Sralph if ((fp = fopen(line, "r")) == NULL) { 10912382Sralph printf("\tcannot open lock file\n"); 11012382Sralph return; 11112382Sralph } 11213146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 11313168Sralph (void) fclose(fp); /* unlocks as well */ 11412382Sralph printf("\tno daemon to abort\n"); 11512382Sralph return; 11612382Sralph } 11712382Sralph (void) fclose(fp); 11816755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 11912382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 12012382Sralph else 12112382Sralph printf("\tdaemon (pid %d) killed\n", pid); 12212382Sralph } 12312382Sralph 12412382Sralph /* 12512382Sralph * Remove all spool files and temporaries from the spooling area. 12612382Sralph */ 12712382Sralph clean(argc, argv) 12812382Sralph char *argv[]; 12912382Sralph { 13012382Sralph register int c, status; 13112382Sralph register char *cp1, *cp2; 13212382Sralph char prbuf[100]; 13312382Sralph 13412382Sralph if (argc == 1) { 13512382Sralph printf("Usage: clean {all | printer ...}\n"); 13612382Sralph return; 13712382Sralph } 13812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 13912382Sralph printer = prbuf; 14012382Sralph while (getprent(line) > 0) { 14112382Sralph cp1 = prbuf; 14212382Sralph cp2 = line; 14312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 14412382Sralph *cp1++ = c; 14512382Sralph *cp1 = '\0'; 14612382Sralph cleanpr(); 14712382Sralph } 14812382Sralph return; 14912382Sralph } 15012382Sralph while (--argc) { 15112382Sralph printer = *++argv; 15212382Sralph if ((status = pgetent(line, printer)) < 0) { 15312514Sralph printf("cannot open printer description file\n"); 15412382Sralph continue; 15512382Sralph } else if (status == 0) { 15612514Sralph printf("unknown printer %s\n", printer); 15712382Sralph continue; 15812382Sralph } 15912382Sralph cleanpr(); 16012382Sralph } 16112382Sralph } 16212382Sralph 16315719Sralph select(d) 16415719Sralph struct direct *d; 16515719Sralph { 16615719Sralph int c = d->d_name[0]; 16715719Sralph 16815719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 16915719Sralph return(1); 17015719Sralph return(0); 17115719Sralph } 17215719Sralph 17315719Sralph /* 17415719Sralph * Comparison routine for scandir. Sort by job number and machine, then 17515719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 17615719Sralph */ 17715719Sralph sortq(d1, d2) 17815719Sralph struct direct **d1, **d2; 17915719Sralph { 18015719Sralph int c1, c2; 18115719Sralph 18215719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 18315719Sralph return(c1); 18415719Sralph c1 = (*d1)->d_name[0]; 18515719Sralph c2 = (*d2)->d_name[0]; 18615719Sralph if (c1 == c2) 18715719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 18815719Sralph if (c1 == 'c') 18915719Sralph return(-1); 19015719Sralph if (c1 == 'd' || c2 == 'c') 19115719Sralph return(1); 19215719Sralph return(-1); 19315719Sralph } 19415719Sralph 19515719Sralph /* 19615719Sralph * Remove incomplete jobs from spooling area. 19715719Sralph */ 19812382Sralph cleanpr() 19912382Sralph { 20015719Sralph register int i, n; 20115719Sralph register char *cp, *cp1, *lp; 20215719Sralph struct direct **queue; 20315719Sralph int nitems; 20412382Sralph 20512382Sralph bp = pbuf; 20612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 20712382Sralph SD = DEFSPOOL; 20812382Sralph printf("%s:\n", printer); 20912382Sralph 21015719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 21115719Sralph ; 21215719Sralph lp[-1] = '/'; 21315719Sralph 21415719Sralph nitems = scandir(SD, &queue, select, sortq); 21515719Sralph if (nitems < 0) { 21612382Sralph printf("\tcannot examine spool directory\n"); 21712382Sralph return; 21812382Sralph } 21915719Sralph if (nitems == 0) 22015719Sralph return; 22115719Sralph i = 0; 22215719Sralph do { 22315719Sralph cp = queue[i]->d_name; 22415719Sralph if (*cp == 'c') { 22515719Sralph n = 0; 22615719Sralph while (i + 1 < nitems) { 22715719Sralph cp1 = queue[i + 1]->d_name; 22815719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 22915719Sralph break; 23015719Sralph i++; 23115719Sralph n++; 23215719Sralph } 23315719Sralph if (n == 0) { 23415719Sralph strcpy(lp, cp); 23515719Sralph unlinkf(line); 23615719Sralph } 23715719Sralph } else { 23815719Sralph /* 23915719Sralph * Must be a df with no cf (otherwise, it would have 24015719Sralph * been skipped above) or a tf file (which can always 24115719Sralph * be removed). 24215719Sralph */ 24315719Sralph strcpy(lp, cp); 24415719Sralph unlinkf(line); 24512382Sralph } 24615719Sralph } while (++i < nitems); 24712382Sralph } 24815719Sralph 24915719Sralph unlinkf(name) 25015719Sralph char *name; 25115719Sralph { 25215719Sralph if (unlink(name) < 0) 25315719Sralph printf("\tcannot remove %s\n", name); 25415719Sralph else 25515719Sralph printf("\tremoved %s\n", name); 25615719Sralph } 25712382Sralph 25812382Sralph /* 25912382Sralph * Enable queuing to the printer (allow lpr's). 26012382Sralph */ 26112382Sralph enable(argc, argv) 26212382Sralph char *argv[]; 26312382Sralph { 26412382Sralph register int c, status; 26512382Sralph register char *cp1, *cp2; 26612382Sralph char prbuf[100]; 26712382Sralph 26812382Sralph if (argc == 1) { 26912382Sralph printf("Usage: enable {all | printer ...}\n"); 27012382Sralph return; 27112382Sralph } 27212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 27312382Sralph printer = prbuf; 27412382Sralph while (getprent(line) > 0) { 27512382Sralph cp1 = prbuf; 27612382Sralph cp2 = line; 27712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 27812382Sralph *cp1++ = c; 27912382Sralph *cp1 = '\0'; 28012382Sralph enablepr(); 28112382Sralph } 28212382Sralph return; 28312382Sralph } 28412382Sralph while (--argc) { 28512382Sralph printer = *++argv; 28612382Sralph if ((status = pgetent(line, printer)) < 0) { 28712514Sralph printf("cannot open printer description file\n"); 28812382Sralph continue; 28912382Sralph } else if (status == 0) { 29012514Sralph printf("unknown printer %s\n", printer); 29112382Sralph continue; 29212382Sralph } 29312382Sralph enablepr(); 29412382Sralph } 29512382Sralph } 29612382Sralph 29712382Sralph enablepr() 29812382Sralph { 29912382Sralph struct stat stbuf; 30012382Sralph 30112382Sralph bp = pbuf; 30212382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 30312382Sralph SD = DEFSPOOL; 30412382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 30512382Sralph LO = DEFLOCK; 30612382Sralph (void) sprintf(line, "%s/%s", SD, LO); 30712382Sralph printf("%s:\n", printer); 30812382Sralph 30912382Sralph /* 31012382Sralph * Turn off the group execute bit of the lock file to enable queuing. 31112382Sralph */ 31212382Sralph if (stat(line, &stbuf) >= 0) { 31312382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 31412514Sralph printf("\tcannot enable queuing\n"); 31512382Sralph else 31612382Sralph printf("\tqueuing enabled\n"); 31712382Sralph } 31812382Sralph } 31912382Sralph 32012382Sralph /* 32112382Sralph * Disable queuing. 32212382Sralph */ 32312382Sralph disable(argc, argv) 32412382Sralph char *argv[]; 32512382Sralph { 32612382Sralph register int c, status; 32712382Sralph register char *cp1, *cp2; 32812382Sralph char prbuf[100]; 32912382Sralph 33012382Sralph if (argc == 1) { 33112382Sralph printf("Usage: disable {all | printer ...}\n"); 33212382Sralph return; 33312382Sralph } 33412382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 33512382Sralph printer = prbuf; 33612382Sralph while (getprent(line) > 0) { 33712382Sralph cp1 = prbuf; 33812382Sralph cp2 = line; 33912382Sralph while ((c = *cp2++) && c != '|' && c != ':') 34012382Sralph *cp1++ = c; 34112382Sralph *cp1 = '\0'; 34212382Sralph disablepr(); 34312382Sralph } 34412382Sralph return; 34512382Sralph } 34612382Sralph while (--argc) { 34712382Sralph printer = *++argv; 34812382Sralph if ((status = pgetent(line, printer)) < 0) { 34912514Sralph printf("cannot open printer description file\n"); 35012382Sralph continue; 35112382Sralph } else if (status == 0) { 35212514Sralph printf("unknown printer %s\n", printer); 35312382Sralph continue; 35412382Sralph } 35512382Sralph disablepr(); 35612382Sralph } 35712382Sralph } 35812382Sralph 35912382Sralph disablepr() 36012382Sralph { 36112382Sralph register int fd; 36212382Sralph struct stat stbuf; 36312382Sralph 36412382Sralph bp = pbuf; 36512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 36612382Sralph SD = DEFSPOOL; 36712382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 36812382Sralph LO = DEFLOCK; 36912382Sralph (void) sprintf(line, "%s/%s", SD, LO); 37012382Sralph printf("%s:\n", printer); 37112382Sralph /* 37212382Sralph * Turn on the group execute bit of the lock file to disable queuing. 37312382Sralph */ 37412382Sralph if (stat(line, &stbuf) >= 0) { 37512382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 37612382Sralph printf("\tcannot disable queuing\n"); 37712382Sralph else 37812382Sralph printf("\tqueuing disabled\n"); 37912382Sralph } else if (errno == ENOENT) { 38013146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 38112382Sralph printf("\tcannot create lock file\n"); 38212382Sralph else { 38312382Sralph (void) close(fd); 38412382Sralph printf("\tqueuing disabled\n"); 38512382Sralph } 38612382Sralph return; 38712382Sralph } else 38812382Sralph printf("\tcannot stat lock file\n"); 38912382Sralph } 39012382Sralph 39112382Sralph /* 39215907Sralph * Disable queuing and printing and put a message into the status file 39315907Sralph * (reason for being down). 39415907Sralph */ 39515907Sralph down(argc, argv) 39615907Sralph char *argv[]; 39715907Sralph { 39815907Sralph register int c, status; 39915907Sralph register char *cp1, *cp2; 40015907Sralph char prbuf[100]; 40115907Sralph 40215907Sralph if (argc == 1) { 40316204Sralph printf("Usage: down {all | printer} [message ...]\n"); 40415907Sralph return; 40515907Sralph } 40615907Sralph if (!strcmp(argv[1], "all")) { 40715907Sralph printer = prbuf; 40815907Sralph while (getprent(line) > 0) { 40915907Sralph cp1 = prbuf; 41015907Sralph cp2 = line; 41115907Sralph while ((c = *cp2++) && c != '|' && c != ':') 41215907Sralph *cp1++ = c; 41315907Sralph *cp1 = '\0'; 41415907Sralph putmsg(argc - 2, argv + 2); 41515907Sralph } 41615907Sralph return; 41715907Sralph } 41815907Sralph printer = argv[1]; 41915907Sralph if ((status = pgetent(line, printer)) < 0) { 42015907Sralph printf("cannot open printer description file\n"); 42115907Sralph return; 42215907Sralph } else if (status == 0) { 42315907Sralph printf("unknown printer %s\n", printer); 42415907Sralph return; 42515907Sralph } 42615907Sralph putmsg(argc - 2, argv + 2); 42715907Sralph } 42815907Sralph 42915907Sralph putmsg(argc, argv) 43015907Sralph char **argv; 43115907Sralph { 43215907Sralph register int fd; 43315907Sralph register char *cp1, *cp2; 43415907Sralph char buf[1024]; 43515907Sralph struct stat stbuf; 43615907Sralph 43715907Sralph bp = pbuf; 43815907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 43915907Sralph SD = DEFSPOOL; 44015907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 44115907Sralph LO = DEFLOCK; 44215907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 44315907Sralph ST = DEFSTAT; 44415907Sralph printf("%s:\n", printer); 44515907Sralph /* 44615907Sralph * Turn on the group execute bit of the lock file to disable queuing and 44715907Sralph * turn on the owner execute bit of the lock file to disable printing. 44815907Sralph */ 44915907Sralph (void) sprintf(line, "%s/%s", SD, LO); 45015907Sralph if (stat(line, &stbuf) >= 0) { 45115907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 45215907Sralph printf("\tcannot disable queuing\n"); 45315907Sralph else 45415907Sralph printf("\tprinter and queuing disabled\n"); 45515907Sralph } else if (errno == ENOENT) { 45615907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 45715907Sralph printf("\tcannot create lock file\n"); 45815907Sralph else { 45915907Sralph (void) close(fd); 46015907Sralph printf("\tprinter and queuing disabled\n"); 46115907Sralph } 46215907Sralph return; 46315907Sralph } else 46415907Sralph printf("\tcannot stat lock file\n"); 46515907Sralph /* 46615907Sralph * Write the message into the status file. 46715907Sralph */ 46815907Sralph (void) sprintf(line, "%s/%s", SD, ST); 46915907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 47015907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 47115907Sralph printf("\tcannot create status file\n"); 47215907Sralph return; 47315907Sralph } 47415907Sralph (void) ftruncate(fd, 0); 47516204Sralph if (argc <= 0) { 47616204Sralph (void) write(fd, "\n", 1); 47716204Sralph (void) close(fd); 47816204Sralph return; 47916204Sralph } 48015907Sralph cp1 = buf; 48115907Sralph while (--argc >= 0) { 48215907Sralph cp2 = *argv++; 48315907Sralph while (*cp1++ = *cp2++) 48415907Sralph ; 48515907Sralph cp1[-1] = ' '; 48615907Sralph } 48715907Sralph cp1[-1] = '\n'; 48815907Sralph *cp1 = '\0'; 48915907Sralph (void) write(fd, buf, strlen(buf)); 49015907Sralph (void) close(fd); 49115907Sralph } 49215907Sralph 49315907Sralph /* 49412382Sralph * Exit lpc 49512382Sralph */ 49612382Sralph quit(argc, argv) 49712382Sralph char *argv[]; 49812382Sralph { 49912382Sralph exit(0); 50012382Sralph } 50112382Sralph 50212382Sralph /* 50316755Sralph * Kill and restart the daemon. 50412382Sralph */ 50512382Sralph restart(argc, argv) 50612382Sralph char *argv[]; 50712382Sralph { 50812382Sralph register int c, status; 50912382Sralph register char *cp1, *cp2; 51012382Sralph char prbuf[100]; 51112382Sralph 51212382Sralph if (argc == 1) { 51312382Sralph printf("Usage: restart {all | printer ...}\n"); 51412382Sralph return; 51512382Sralph } 51612382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 51712382Sralph printer = prbuf; 51812382Sralph while (getprent(line) > 0) { 51912382Sralph cp1 = prbuf; 52012382Sralph cp2 = line; 52112382Sralph while ((c = *cp2++) && c != '|' && c != ':') 52212382Sralph *cp1++ = c; 52312382Sralph *cp1 = '\0'; 52416755Sralph abortpr(0); 52512382Sralph startpr(0); 52612382Sralph } 52712382Sralph return; 52812382Sralph } 52912382Sralph while (--argc) { 53012382Sralph printer = *++argv; 53112382Sralph if ((status = pgetent(line, printer)) < 0) { 53212514Sralph printf("cannot open printer description file\n"); 53312382Sralph continue; 53412382Sralph } else if (status == 0) { 53512514Sralph printf("unknown printer %s\n", printer); 53612382Sralph continue; 53712382Sralph } 53816755Sralph abortpr(0); 53912382Sralph startpr(0); 54012382Sralph } 54112382Sralph } 54212382Sralph 54312382Sralph /* 54412382Sralph * Enable printing on the specified printer and startup the daemon. 54512382Sralph */ 54612382Sralph start(argc, argv) 54712382Sralph char *argv[]; 54812382Sralph { 54912382Sralph register int c, status; 55012382Sralph register char *cp1, *cp2; 55112382Sralph char prbuf[100]; 55212382Sralph 55312382Sralph if (argc == 1) { 55412382Sralph printf("Usage: start {all | printer ...}\n"); 55512382Sralph return; 55612382Sralph } 55712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 55812382Sralph printer = prbuf; 55912382Sralph while (getprent(line) > 0) { 56012382Sralph cp1 = prbuf; 56112382Sralph cp2 = line; 56212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 56312382Sralph *cp1++ = c; 56412382Sralph *cp1 = '\0'; 56512382Sralph startpr(1); 56612382Sralph } 56712382Sralph return; 56812382Sralph } 56912382Sralph while (--argc) { 57012382Sralph printer = *++argv; 57112382Sralph if ((status = pgetent(line, printer)) < 0) { 57212514Sralph printf("cannot open printer description file\n"); 57312382Sralph continue; 57412382Sralph } else if (status == 0) { 57512514Sralph printf("unknown printer %s\n", printer); 57612382Sralph continue; 57712382Sralph } 57812382Sralph startpr(1); 57912382Sralph } 58012382Sralph } 58112382Sralph 58212382Sralph startpr(enable) 58312382Sralph { 58412382Sralph struct stat stbuf; 58512382Sralph 58612382Sralph bp = pbuf; 58712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 58812382Sralph SD = DEFSPOOL; 58912382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 59012382Sralph LO = DEFLOCK; 59112382Sralph (void) sprintf(line, "%s/%s", SD, LO); 59212382Sralph printf("%s:\n", printer); 59312382Sralph 59412382Sralph /* 59512382Sralph * Turn off the owner execute bit of the lock file to enable printing. 59612382Sralph */ 59712382Sralph if (enable && stat(line, &stbuf) >= 0) { 59816771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 59912382Sralph printf("\tcannot enable printing\n"); 60012382Sralph else 60112382Sralph printf("\tprinting enabled\n"); 60212382Sralph } 60313727Sroot if (!startdaemon(printer)) 60412382Sralph printf("\tcouldn't start daemon\n"); 60512382Sralph else 60612382Sralph printf("\tdaemon started\n"); 60712382Sralph } 60812382Sralph 60912382Sralph /* 61012382Sralph * Print the status of each queue listed or all the queues. 61112382Sralph */ 61212382Sralph status(argc, argv) 61312382Sralph char *argv[]; 61412382Sralph { 61512382Sralph register int c, status; 61612382Sralph register char *cp1, *cp2; 61712382Sralph char prbuf[100]; 61812382Sralph 61912382Sralph if (argc == 1) { 62012382Sralph printer = prbuf; 62112382Sralph while (getprent(line) > 0) { 62212382Sralph cp1 = prbuf; 62312382Sralph cp2 = line; 62412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 62512382Sralph *cp1++ = c; 62612382Sralph *cp1 = '\0'; 62712382Sralph prstat(); 62812382Sralph } 62912382Sralph return; 63012382Sralph } 63112382Sralph while (--argc) { 63212382Sralph printer = *++argv; 63312382Sralph if ((status = pgetent(line, printer)) < 0) { 63412514Sralph printf("cannot open printer description file\n"); 63512382Sralph continue; 63612382Sralph } else if (status == 0) { 63712514Sralph printf("unknown printer %s\n", printer); 63812382Sralph continue; 63912382Sralph } 64012382Sralph prstat(); 64112382Sralph } 64212382Sralph } 64312382Sralph 64412382Sralph /* 64512382Sralph * Print the status of the printer queue. 64612382Sralph */ 64712382Sralph prstat() 64812382Sralph { 64912382Sralph struct stat stbuf; 65012382Sralph register int fd, i; 65112382Sralph register struct direct *dp; 65212382Sralph DIR *dirp; 65312382Sralph 65412382Sralph bp = pbuf; 65512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 65612382Sralph SD = DEFSPOOL; 65712382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 65812382Sralph LO = DEFLOCK; 65912382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 66012382Sralph ST = DEFSTAT; 66112382Sralph printf("%s:\n", printer); 66212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 66312382Sralph if (stat(line, &stbuf) >= 0) { 66412382Sralph printf("\tqueuing is %s\n", 66512382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 66612382Sralph printf("\tprinting is %s\n", 66712382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 66812382Sralph } else { 66912382Sralph printf("\tqueuing is enabled\n"); 67012382Sralph printf("\tprinting is enabled\n"); 67112382Sralph } 67212382Sralph if ((dirp = opendir(SD)) == NULL) { 67312382Sralph printf("\tcannot examine spool directory\n"); 67412382Sralph return; 67512382Sralph } 67612382Sralph i = 0; 67712382Sralph while ((dp = readdir(dirp)) != NULL) { 67812382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 67912382Sralph i++; 68012382Sralph } 68112382Sralph closedir(dirp); 68212382Sralph if (i == 0) 68312382Sralph printf("\tno entries\n"); 68412382Sralph else if (i == 1) 68512382Sralph printf("\t1 entry in spool area\n"); 68612382Sralph else 68712382Sralph printf("\t%d entries in spool area\n", i); 68813146Ssam fd = open(line, O_RDONLY); 68913146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 69013168Sralph (void) close(fd); /* unlocks as well */ 69112382Sralph printf("\tno daemon present\n"); 69212382Sralph return; 69312382Sralph } 69412382Sralph (void) close(fd); 69512382Sralph putchar('\t'); 69612382Sralph (void) sprintf(line, "%s/%s", SD, ST); 69713146Ssam fd = open(line, O_RDONLY); 69813146Ssam if (fd >= 0) { 69913146Ssam (void) flock(fd, LOCK_SH); 70012382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 70112382Sralph (void) fwrite(line, 1, i, stdout); 70213168Sralph (void) close(fd); /* unlocks as well */ 70312382Sralph } 70412382Sralph } 70512382Sralph 70612382Sralph /* 70712382Sralph * Stop the specified daemon after completing the current job and disable 70812382Sralph * printing. 70912382Sralph */ 71012382Sralph stop(argc, argv) 71112382Sralph char *argv[]; 71212382Sralph { 71312382Sralph register int c, status; 71412382Sralph register char *cp1, *cp2; 71512382Sralph char prbuf[100]; 71612382Sralph 71712382Sralph if (argc == 1) { 71812382Sralph printf("Usage: stop {all | printer ...}\n"); 71912382Sralph return; 72012382Sralph } 72112382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 72212382Sralph printer = prbuf; 72312382Sralph while (getprent(line) > 0) { 72412382Sralph cp1 = prbuf; 72512382Sralph cp2 = line; 72612382Sralph while ((c = *cp2++) && c != '|' && c != ':') 72712382Sralph *cp1++ = c; 72812382Sralph *cp1 = '\0'; 72912382Sralph stoppr(); 73012382Sralph } 73112382Sralph return; 73212382Sralph } 73312382Sralph while (--argc) { 73412382Sralph printer = *++argv; 73512382Sralph if ((status = pgetent(line, printer)) < 0) { 73612514Sralph printf("cannot open printer description file\n"); 73712382Sralph continue; 73812382Sralph } else if (status == 0) { 73912514Sralph printf("unknown printer %s\n", printer); 74012382Sralph continue; 74112382Sralph } 74212382Sralph stoppr(); 74312382Sralph } 74412382Sralph } 74512382Sralph 74612382Sralph stoppr() 74712382Sralph { 74812382Sralph register int fd; 74912382Sralph struct stat stbuf; 75012382Sralph 75112382Sralph bp = pbuf; 75212382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 75312382Sralph SD = DEFSPOOL; 75412382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 75512382Sralph LO = DEFLOCK; 75612382Sralph (void) sprintf(line, "%s/%s", SD, LO); 75712382Sralph printf("%s:\n", printer); 75812382Sralph 75912382Sralph /* 76012382Sralph * Turn on the owner execute bit of the lock file to disable printing. 76112382Sralph */ 76212382Sralph if (stat(line, &stbuf) >= 0) { 76312382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 76412382Sralph printf("\tcannot disable printing\n"); 76512382Sralph else 76612382Sralph printf("\tprinting disabled\n"); 76712382Sralph } else if (errno == ENOENT) { 76813146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 76912382Sralph printf("\tcannot create lock file\n"); 77012382Sralph else { 77112382Sralph (void) close(fd); 77212382Sralph printf("\tprinting disabled\n"); 77312382Sralph } 77412382Sralph } else 77512382Sralph printf("\tcannot stat lock file\n"); 77612382Sralph } 77713727Sroot 77815719Sralph struct queue **queue; 77915719Sralph int nitems; 78015719Sralph time_t mtime; 78115719Sralph 78213727Sroot /* 78313727Sroot * Put the specified jobs at the top of printer queue. 78413727Sroot */ 78513727Sroot topq(argc, argv) 78613727Sroot char *argv[]; 78713727Sroot { 78815719Sralph register int n, i; 78913727Sroot struct stat stbuf; 79013727Sroot register char *cfname; 79115719Sralph int status, changed; 79213727Sroot 79315719Sralph if (argc < 3) { 79413727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 79513727Sroot return; 79613727Sroot } 79713727Sroot 79813727Sroot --argc; 79913727Sroot printer = *++argv; 80013727Sroot status = pgetent(line, printer); 80113727Sroot if (status < 0) { 80213727Sroot printf("cannot open printer description file\n"); 80313727Sroot return; 80414151Sralph } else if (status == 0) { 80513727Sroot printf("%s: unknown printer\n", printer); 80613727Sroot return; 80713727Sroot } 80813727Sroot bp = pbuf; 80913727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 81013727Sroot SD = DEFSPOOL; 81113727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 81213727Sroot LO = DEFLOCK; 81313727Sroot printf("%s:\n", printer); 81413727Sroot 81513727Sroot if (chdir(SD) < 0) { 81613727Sroot printf("\tcannot chdir to %s\n", SD); 81713727Sroot return; 81813727Sroot } 81913727Sroot nitems = getq(&queue); 82015719Sralph if (nitems == 0) 82115719Sralph return; 82215719Sralph changed = 0; 82315719Sralph mtime = queue[0]->q_time; 82415719Sralph for (i = argc; --i; ) { 82515719Sralph if (doarg(argv[i]) == 0) { 82615719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 82713727Sroot continue; 82815719Sralph } else 82914151Sralph changed++; 83013727Sroot } 83115719Sralph for (i = 0; i < nitems; i++) 83215719Sralph free(queue[i]); 83315719Sralph free(queue); 83415719Sralph if (!changed) { 83515719Sralph printf("\tqueue order unchanged\n"); 83615719Sralph return; 83713727Sroot } 83813727Sroot /* 83913727Sroot * Turn on the public execute bit of the lock file to 84013727Sroot * get lpd to rebuild the queue after the current job. 84113727Sroot */ 84214151Sralph if (changed && stat(LO, &stbuf) >= 0) 84314151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 84413727Sroot } 84513727Sroot 84615719Sralph /* 84715719Sralph * Reposition the job by changing the modification time of 84815719Sralph * the control file. 84913727Sroot */ 85015719Sralph touch(q) 85115719Sralph struct queue *q; 85213727Sroot { 85315719Sralph struct timeval tvp[2]; 85413727Sroot 85515719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 85615719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 85715719Sralph return(utimes(q->q_name, tvp)); 85813727Sroot } 85913727Sroot 86013727Sroot /* 86113727Sroot * Checks if specified job name is in the printer's queue. 86213727Sroot * Returns: negative (-1) if argument name is not in the queue. 86313727Sroot */ 86415719Sralph doarg(job) 86513727Sroot char *job; 86613727Sroot { 86715719Sralph register struct queue **qq; 86815719Sralph register int jobnum, n; 86915719Sralph register char *cp, *machine; 87015719Sralph int cnt = 0; 87114151Sralph FILE *fp; 87213727Sroot 87315719Sralph /* 87415719Sralph * Look for a job item consisting of system name, colon, number 87515719Sralph * (example: ucbarpa:114) 87615719Sralph */ 87715719Sralph if ((cp = index(job, ':')) != NULL) { 87815719Sralph machine = job; 87915719Sralph *cp++ = '\0'; 88015719Sralph job = cp; 88115719Sralph } else 88215719Sralph machine = NULL; 88315719Sralph 88415719Sralph /* 88515719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 88615719Sralph */ 88713727Sroot if (isdigit(*job)) { 88813727Sroot jobnum = 0; 88913727Sroot do 89013727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 89113727Sroot while (isdigit(*job)); 89215719Sralph for (qq = queue + nitems; --qq >= queue; ) { 89313727Sroot n = 0; 89415719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 89514151Sralph n = n * 10 + (*cp++ - '0'); 89615719Sralph if (jobnum != n) 89715719Sralph continue; 89815719Sralph if (*job && strcmp(job, cp) != 0) 89915719Sralph continue; 90015719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 90115719Sralph continue; 90215719Sralph if (touch(*qq) == 0) { 90315719Sralph printf("\tmoved %s\n", (*qq)->q_name); 90415719Sralph cnt++; 90515719Sralph } 90613727Sroot } 90715719Sralph return(cnt); 90815719Sralph } 90915719Sralph /* 91015719Sralph * Process item consisting of owner's name (example: henry). 91115719Sralph */ 91215719Sralph for (qq = queue + nitems; --qq >= queue; ) { 91315719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 91413727Sroot continue; 91515719Sralph while (getline(fp) > 0) 91615719Sralph if (line[0] == 'P') 91715719Sralph break; 91815719Sralph (void) fclose(fp); 91915719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 92015719Sralph continue; 92115719Sralph if (touch(*qq) == 0) { 92215719Sralph printf("\tmoved %s\n", (*qq)->q_name); 92315719Sralph cnt++; 92413727Sroot } 92513727Sroot } 92615719Sralph return(cnt); 92713727Sroot } 92816755Sralph 92916755Sralph /* 93016755Sralph * Enable everything and start printer (undo `down'). 93116755Sralph */ 93216755Sralph up(argc, argv) 93316755Sralph char *argv[]; 93416755Sralph { 93516755Sralph register int c, status; 93616755Sralph register char *cp1, *cp2; 93716755Sralph char prbuf[100]; 93816755Sralph 93916755Sralph if (argc == 1) { 94016755Sralph printf("Usage: up {all | printer ...}\n"); 94116755Sralph return; 94216755Sralph } 94316755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 94416755Sralph printer = prbuf; 94516755Sralph while (getprent(line) > 0) { 94616755Sralph cp1 = prbuf; 94716755Sralph cp2 = line; 94816755Sralph while ((c = *cp2++) && c != '|' && c != ':') 94916755Sralph *cp1++ = c; 95016755Sralph *cp1 = '\0'; 95116755Sralph startpr(2); 95216755Sralph } 95316755Sralph return; 95416755Sralph } 95516755Sralph while (--argc) { 95616755Sralph printer = *++argv; 95716755Sralph if ((status = pgetent(line, printer)) < 0) { 95816755Sralph printf("cannot open printer description file\n"); 95916755Sralph continue; 96016755Sralph } else if (status == 0) { 96116755Sralph printf("unknown printer %s\n", printer); 96216755Sralph continue; 96316755Sralph } 96416755Sralph startpr(2); 96516755Sralph } 96616755Sralph } 967