122424Sdist /* 222424Sdist * Copyright (c) 1983 Regents of the University of California. 3*34203Sbostic * All rights reserved. 4*34203Sbostic * 5*34203Sbostic * Redistribution and use in source and binary forms are permitted 6*34203Sbostic * provided that this notice is preserved and that due credit is given 7*34203Sbostic * to the University of California at Berkeley. The name of the University 8*34203Sbostic * may not be used to endorse or promote products derived from this 9*34203Sbostic * software without specific prior written permission. This software 10*34203Sbostic * is provided ``as is'' without express or implied warranty. 1122424Sdist */ 1222424Sdist 1312382Sralph #ifndef lint 14*34203Sbostic static char sccsid[] = "@(#)cmds.c 5.3 (Berkeley) 05/05/88"; 15*34203Sbostic #endif /* not lint */ 1612382Sralph 1712382Sralph /* 1815719Sralph * lpc -- line printer control program -- commands: 1912382Sralph */ 2012382Sralph 2112382Sralph #include "lp.h" 2215719Sralph #include <sys/time.h> 2312382Sralph 2412382Sralph /* 2512382Sralph * kill an existing daemon and disable printing. 2612382Sralph */ 2712382Sralph abort(argc, argv) 2812382Sralph char *argv[]; 2912382Sralph { 3012382Sralph register int c, status; 3112382Sralph register char *cp1, *cp2; 3212382Sralph char prbuf[100]; 3312382Sralph 3412382Sralph if (argc == 1) { 3512382Sralph printf("Usage: abort {all | printer ...}\n"); 3612382Sralph return; 3712382Sralph } 3812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 3912382Sralph printer = prbuf; 4012382Sralph while (getprent(line) > 0) { 4112382Sralph cp1 = prbuf; 4212382Sralph cp2 = line; 4312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 4412382Sralph *cp1++ = c; 4512382Sralph *cp1 = '\0'; 4616755Sralph abortpr(1); 4712382Sralph } 4812382Sralph return; 4912382Sralph } 5012382Sralph while (--argc) { 5112382Sralph printer = *++argv; 5212382Sralph if ((status = pgetent(line, printer)) < 0) { 5312514Sralph printf("cannot open printer description file\n"); 5412382Sralph continue; 5512382Sralph } else if (status == 0) { 5612514Sralph printf("unknown printer %s\n", printer); 5712382Sralph continue; 5812382Sralph } 5916755Sralph abortpr(1); 6012382Sralph } 6112382Sralph } 6212382Sralph 6316755Sralph abortpr(dis) 6412382Sralph { 6512382Sralph register FILE *fp; 6612382Sralph struct stat stbuf; 6712382Sralph int pid, fd; 6812382Sralph 6912382Sralph bp = pbuf; 7012382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 7112382Sralph SD = DEFSPOOL; 7212382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 7312382Sralph LO = DEFLOCK; 7412382Sralph (void) sprintf(line, "%s/%s", SD, LO); 7512382Sralph printf("%s:\n", printer); 7612382Sralph 7712382Sralph /* 7812382Sralph * Turn on the owner execute bit of the lock file to disable printing. 7912382Sralph */ 8016755Sralph if (dis) { 8116755Sralph if (stat(line, &stbuf) >= 0) { 8216755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 8316755Sralph printf("\tcannot disable printing\n"); 8416755Sralph else 8516755Sralph printf("\tprinting disabled\n"); 8616755Sralph } else if (errno == ENOENT) { 8716755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 8816755Sralph printf("\tcannot create lock file\n"); 8916755Sralph else { 9016755Sralph (void) close(fd); 9116755Sralph printf("\tprinting disabled\n"); 9216755Sralph printf("\tno daemon to abort\n"); 9316755Sralph } 9416755Sralph return; 9516755Sralph } else { 9616755Sralph printf("\tcannot stat lock file\n"); 9716755Sralph return; 9812382Sralph } 9912382Sralph } 10012382Sralph /* 10112382Sralph * Kill the current daemon to stop printing now. 10212382Sralph */ 10312382Sralph if ((fp = fopen(line, "r")) == NULL) { 10412382Sralph printf("\tcannot open lock file\n"); 10512382Sralph return; 10612382Sralph } 10713146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 10813168Sralph (void) fclose(fp); /* unlocks as well */ 10912382Sralph printf("\tno daemon to abort\n"); 11012382Sralph return; 11112382Sralph } 11212382Sralph (void) fclose(fp); 11316755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 11412382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 11512382Sralph else 11612382Sralph printf("\tdaemon (pid %d) killed\n", pid); 11712382Sralph } 11812382Sralph 11912382Sralph /* 12012382Sralph * Remove all spool files and temporaries from the spooling area. 12112382Sralph */ 12212382Sralph clean(argc, argv) 12312382Sralph char *argv[]; 12412382Sralph { 12512382Sralph register int c, status; 12612382Sralph register char *cp1, *cp2; 12712382Sralph char prbuf[100]; 12812382Sralph 12912382Sralph if (argc == 1) { 13012382Sralph printf("Usage: clean {all | printer ...}\n"); 13112382Sralph return; 13212382Sralph } 13312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 13412382Sralph printer = prbuf; 13512382Sralph while (getprent(line) > 0) { 13612382Sralph cp1 = prbuf; 13712382Sralph cp2 = line; 13812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 13912382Sralph *cp1++ = c; 14012382Sralph *cp1 = '\0'; 14112382Sralph cleanpr(); 14212382Sralph } 14312382Sralph return; 14412382Sralph } 14512382Sralph while (--argc) { 14612382Sralph printer = *++argv; 14712382Sralph if ((status = pgetent(line, printer)) < 0) { 14812514Sralph printf("cannot open printer description file\n"); 14912382Sralph continue; 15012382Sralph } else if (status == 0) { 15112514Sralph printf("unknown printer %s\n", printer); 15212382Sralph continue; 15312382Sralph } 15412382Sralph cleanpr(); 15512382Sralph } 15612382Sralph } 15712382Sralph 15815719Sralph select(d) 15915719Sralph struct direct *d; 16015719Sralph { 16115719Sralph int c = d->d_name[0]; 16215719Sralph 16315719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 16415719Sralph return(1); 16515719Sralph return(0); 16615719Sralph } 16715719Sralph 16815719Sralph /* 16915719Sralph * Comparison routine for scandir. Sort by job number and machine, then 17015719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 17115719Sralph */ 17215719Sralph sortq(d1, d2) 17315719Sralph struct direct **d1, **d2; 17415719Sralph { 17515719Sralph int c1, c2; 17615719Sralph 17715719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 17815719Sralph return(c1); 17915719Sralph c1 = (*d1)->d_name[0]; 18015719Sralph c2 = (*d2)->d_name[0]; 18115719Sralph if (c1 == c2) 18215719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 18315719Sralph if (c1 == 'c') 18415719Sralph return(-1); 18515719Sralph if (c1 == 'd' || c2 == 'c') 18615719Sralph return(1); 18715719Sralph return(-1); 18815719Sralph } 18915719Sralph 19015719Sralph /* 19115719Sralph * Remove incomplete jobs from spooling area. 19215719Sralph */ 19312382Sralph cleanpr() 19412382Sralph { 19515719Sralph register int i, n; 19615719Sralph register char *cp, *cp1, *lp; 19715719Sralph struct direct **queue; 19815719Sralph int nitems; 19912382Sralph 20012382Sralph bp = pbuf; 20112382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 20212382Sralph SD = DEFSPOOL; 20312382Sralph printf("%s:\n", printer); 20412382Sralph 20515719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 20615719Sralph ; 20715719Sralph lp[-1] = '/'; 20815719Sralph 20915719Sralph nitems = scandir(SD, &queue, select, sortq); 21015719Sralph if (nitems < 0) { 21112382Sralph printf("\tcannot examine spool directory\n"); 21212382Sralph return; 21312382Sralph } 21415719Sralph if (nitems == 0) 21515719Sralph return; 21615719Sralph i = 0; 21715719Sralph do { 21815719Sralph cp = queue[i]->d_name; 21915719Sralph if (*cp == 'c') { 22015719Sralph n = 0; 22115719Sralph while (i + 1 < nitems) { 22215719Sralph cp1 = queue[i + 1]->d_name; 22315719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 22415719Sralph break; 22515719Sralph i++; 22615719Sralph n++; 22715719Sralph } 22815719Sralph if (n == 0) { 22915719Sralph strcpy(lp, cp); 23015719Sralph unlinkf(line); 23115719Sralph } 23215719Sralph } else { 23315719Sralph /* 23415719Sralph * Must be a df with no cf (otherwise, it would have 23515719Sralph * been skipped above) or a tf file (which can always 23615719Sralph * be removed). 23715719Sralph */ 23815719Sralph strcpy(lp, cp); 23915719Sralph unlinkf(line); 24012382Sralph } 24115719Sralph } while (++i < nitems); 24212382Sralph } 24315719Sralph 24415719Sralph unlinkf(name) 24515719Sralph char *name; 24615719Sralph { 24715719Sralph if (unlink(name) < 0) 24815719Sralph printf("\tcannot remove %s\n", name); 24915719Sralph else 25015719Sralph printf("\tremoved %s\n", name); 25115719Sralph } 25212382Sralph 25312382Sralph /* 25412382Sralph * Enable queuing to the printer (allow lpr's). 25512382Sralph */ 25612382Sralph enable(argc, argv) 25712382Sralph char *argv[]; 25812382Sralph { 25912382Sralph register int c, status; 26012382Sralph register char *cp1, *cp2; 26112382Sralph char prbuf[100]; 26212382Sralph 26312382Sralph if (argc == 1) { 26412382Sralph printf("Usage: enable {all | printer ...}\n"); 26512382Sralph return; 26612382Sralph } 26712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 26812382Sralph printer = prbuf; 26912382Sralph while (getprent(line) > 0) { 27012382Sralph cp1 = prbuf; 27112382Sralph cp2 = line; 27212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 27312382Sralph *cp1++ = c; 27412382Sralph *cp1 = '\0'; 27512382Sralph enablepr(); 27612382Sralph } 27712382Sralph return; 27812382Sralph } 27912382Sralph while (--argc) { 28012382Sralph printer = *++argv; 28112382Sralph if ((status = pgetent(line, printer)) < 0) { 28212514Sralph printf("cannot open printer description file\n"); 28312382Sralph continue; 28412382Sralph } else if (status == 0) { 28512514Sralph printf("unknown printer %s\n", printer); 28612382Sralph continue; 28712382Sralph } 28812382Sralph enablepr(); 28912382Sralph } 29012382Sralph } 29112382Sralph 29212382Sralph enablepr() 29312382Sralph { 29412382Sralph struct stat stbuf; 29512382Sralph 29612382Sralph bp = pbuf; 29712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 29812382Sralph SD = DEFSPOOL; 29912382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 30012382Sralph LO = DEFLOCK; 30112382Sralph (void) sprintf(line, "%s/%s", SD, LO); 30212382Sralph printf("%s:\n", printer); 30312382Sralph 30412382Sralph /* 30512382Sralph * Turn off the group execute bit of the lock file to enable queuing. 30612382Sralph */ 30712382Sralph if (stat(line, &stbuf) >= 0) { 30812382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 30912514Sralph printf("\tcannot enable queuing\n"); 31012382Sralph else 31112382Sralph printf("\tqueuing enabled\n"); 31212382Sralph } 31312382Sralph } 31412382Sralph 31512382Sralph /* 31612382Sralph * Disable queuing. 31712382Sralph */ 31812382Sralph disable(argc, argv) 31912382Sralph char *argv[]; 32012382Sralph { 32112382Sralph register int c, status; 32212382Sralph register char *cp1, *cp2; 32312382Sralph char prbuf[100]; 32412382Sralph 32512382Sralph if (argc == 1) { 32612382Sralph printf("Usage: disable {all | printer ...}\n"); 32712382Sralph return; 32812382Sralph } 32912382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 33012382Sralph printer = prbuf; 33112382Sralph while (getprent(line) > 0) { 33212382Sralph cp1 = prbuf; 33312382Sralph cp2 = line; 33412382Sralph while ((c = *cp2++) && c != '|' && c != ':') 33512382Sralph *cp1++ = c; 33612382Sralph *cp1 = '\0'; 33712382Sralph disablepr(); 33812382Sralph } 33912382Sralph return; 34012382Sralph } 34112382Sralph while (--argc) { 34212382Sralph printer = *++argv; 34312382Sralph if ((status = pgetent(line, printer)) < 0) { 34412514Sralph printf("cannot open printer description file\n"); 34512382Sralph continue; 34612382Sralph } else if (status == 0) { 34712514Sralph printf("unknown printer %s\n", printer); 34812382Sralph continue; 34912382Sralph } 35012382Sralph disablepr(); 35112382Sralph } 35212382Sralph } 35312382Sralph 35412382Sralph disablepr() 35512382Sralph { 35612382Sralph register int fd; 35712382Sralph struct stat stbuf; 35812382Sralph 35912382Sralph bp = pbuf; 36012382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 36112382Sralph SD = DEFSPOOL; 36212382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 36312382Sralph LO = DEFLOCK; 36412382Sralph (void) sprintf(line, "%s/%s", SD, LO); 36512382Sralph printf("%s:\n", printer); 36612382Sralph /* 36712382Sralph * Turn on the group execute bit of the lock file to disable queuing. 36812382Sralph */ 36912382Sralph if (stat(line, &stbuf) >= 0) { 37012382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 37112382Sralph printf("\tcannot disable queuing\n"); 37212382Sralph else 37312382Sralph printf("\tqueuing disabled\n"); 37412382Sralph } else if (errno == ENOENT) { 37513146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 37612382Sralph printf("\tcannot create lock file\n"); 37712382Sralph else { 37812382Sralph (void) close(fd); 37912382Sralph printf("\tqueuing disabled\n"); 38012382Sralph } 38112382Sralph return; 38212382Sralph } else 38312382Sralph printf("\tcannot stat lock file\n"); 38412382Sralph } 38512382Sralph 38612382Sralph /* 38715907Sralph * Disable queuing and printing and put a message into the status file 38815907Sralph * (reason for being down). 38915907Sralph */ 39015907Sralph down(argc, argv) 39115907Sralph char *argv[]; 39215907Sralph { 39315907Sralph register int c, status; 39415907Sralph register char *cp1, *cp2; 39515907Sralph char prbuf[100]; 39615907Sralph 39715907Sralph if (argc == 1) { 39816204Sralph printf("Usage: down {all | printer} [message ...]\n"); 39915907Sralph return; 40015907Sralph } 40115907Sralph if (!strcmp(argv[1], "all")) { 40215907Sralph printer = prbuf; 40315907Sralph while (getprent(line) > 0) { 40415907Sralph cp1 = prbuf; 40515907Sralph cp2 = line; 40615907Sralph while ((c = *cp2++) && c != '|' && c != ':') 40715907Sralph *cp1++ = c; 40815907Sralph *cp1 = '\0'; 40915907Sralph putmsg(argc - 2, argv + 2); 41015907Sralph } 41115907Sralph return; 41215907Sralph } 41315907Sralph printer = argv[1]; 41415907Sralph if ((status = pgetent(line, printer)) < 0) { 41515907Sralph printf("cannot open printer description file\n"); 41615907Sralph return; 41715907Sralph } else if (status == 0) { 41815907Sralph printf("unknown printer %s\n", printer); 41915907Sralph return; 42015907Sralph } 42115907Sralph putmsg(argc - 2, argv + 2); 42215907Sralph } 42315907Sralph 42415907Sralph putmsg(argc, argv) 42515907Sralph char **argv; 42615907Sralph { 42715907Sralph register int fd; 42815907Sralph register char *cp1, *cp2; 42915907Sralph char buf[1024]; 43015907Sralph struct stat stbuf; 43115907Sralph 43215907Sralph bp = pbuf; 43315907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 43415907Sralph SD = DEFSPOOL; 43515907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 43615907Sralph LO = DEFLOCK; 43715907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 43815907Sralph ST = DEFSTAT; 43915907Sralph printf("%s:\n", printer); 44015907Sralph /* 44115907Sralph * Turn on the group execute bit of the lock file to disable queuing and 44215907Sralph * turn on the owner execute bit of the lock file to disable printing. 44315907Sralph */ 44415907Sralph (void) sprintf(line, "%s/%s", SD, LO); 44515907Sralph if (stat(line, &stbuf) >= 0) { 44615907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 44715907Sralph printf("\tcannot disable queuing\n"); 44815907Sralph else 44915907Sralph printf("\tprinter and queuing disabled\n"); 45015907Sralph } else if (errno == ENOENT) { 45115907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 45215907Sralph printf("\tcannot create lock file\n"); 45315907Sralph else { 45415907Sralph (void) close(fd); 45515907Sralph printf("\tprinter and queuing disabled\n"); 45615907Sralph } 45715907Sralph return; 45815907Sralph } else 45915907Sralph printf("\tcannot stat lock file\n"); 46015907Sralph /* 46115907Sralph * Write the message into the status file. 46215907Sralph */ 46315907Sralph (void) sprintf(line, "%s/%s", SD, ST); 46415907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 46515907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 46615907Sralph printf("\tcannot create status file\n"); 46715907Sralph return; 46815907Sralph } 46915907Sralph (void) ftruncate(fd, 0); 47016204Sralph if (argc <= 0) { 47116204Sralph (void) write(fd, "\n", 1); 47216204Sralph (void) close(fd); 47316204Sralph return; 47416204Sralph } 47515907Sralph cp1 = buf; 47615907Sralph while (--argc >= 0) { 47715907Sralph cp2 = *argv++; 47815907Sralph while (*cp1++ = *cp2++) 47915907Sralph ; 48015907Sralph cp1[-1] = ' '; 48115907Sralph } 48215907Sralph cp1[-1] = '\n'; 48315907Sralph *cp1 = '\0'; 48415907Sralph (void) write(fd, buf, strlen(buf)); 48515907Sralph (void) close(fd); 48615907Sralph } 48715907Sralph 48815907Sralph /* 48912382Sralph * Exit lpc 49012382Sralph */ 49112382Sralph quit(argc, argv) 49212382Sralph char *argv[]; 49312382Sralph { 49412382Sralph exit(0); 49512382Sralph } 49612382Sralph 49712382Sralph /* 49816755Sralph * Kill and restart the daemon. 49912382Sralph */ 50012382Sralph restart(argc, argv) 50112382Sralph char *argv[]; 50212382Sralph { 50312382Sralph register int c, status; 50412382Sralph register char *cp1, *cp2; 50512382Sralph char prbuf[100]; 50612382Sralph 50712382Sralph if (argc == 1) { 50812382Sralph printf("Usage: restart {all | printer ...}\n"); 50912382Sralph return; 51012382Sralph } 51112382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 51212382Sralph printer = prbuf; 51312382Sralph while (getprent(line) > 0) { 51412382Sralph cp1 = prbuf; 51512382Sralph cp2 = line; 51612382Sralph while ((c = *cp2++) && c != '|' && c != ':') 51712382Sralph *cp1++ = c; 51812382Sralph *cp1 = '\0'; 51916755Sralph abortpr(0); 52012382Sralph startpr(0); 52112382Sralph } 52212382Sralph return; 52312382Sralph } 52412382Sralph while (--argc) { 52512382Sralph printer = *++argv; 52612382Sralph if ((status = pgetent(line, printer)) < 0) { 52712514Sralph printf("cannot open printer description file\n"); 52812382Sralph continue; 52912382Sralph } else if (status == 0) { 53012514Sralph printf("unknown printer %s\n", printer); 53112382Sralph continue; 53212382Sralph } 53316755Sralph abortpr(0); 53412382Sralph startpr(0); 53512382Sralph } 53612382Sralph } 53712382Sralph 53812382Sralph /* 53912382Sralph * Enable printing on the specified printer and startup the daemon. 54012382Sralph */ 54112382Sralph start(argc, argv) 54212382Sralph char *argv[]; 54312382Sralph { 54412382Sralph register int c, status; 54512382Sralph register char *cp1, *cp2; 54612382Sralph char prbuf[100]; 54712382Sralph 54812382Sralph if (argc == 1) { 54912382Sralph printf("Usage: start {all | printer ...}\n"); 55012382Sralph return; 55112382Sralph } 55212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 55312382Sralph printer = prbuf; 55412382Sralph while (getprent(line) > 0) { 55512382Sralph cp1 = prbuf; 55612382Sralph cp2 = line; 55712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 55812382Sralph *cp1++ = c; 55912382Sralph *cp1 = '\0'; 56012382Sralph startpr(1); 56112382Sralph } 56212382Sralph return; 56312382Sralph } 56412382Sralph while (--argc) { 56512382Sralph printer = *++argv; 56612382Sralph if ((status = pgetent(line, printer)) < 0) { 56712514Sralph printf("cannot open printer description file\n"); 56812382Sralph continue; 56912382Sralph } else if (status == 0) { 57012514Sralph printf("unknown printer %s\n", printer); 57112382Sralph continue; 57212382Sralph } 57312382Sralph startpr(1); 57412382Sralph } 57512382Sralph } 57612382Sralph 57712382Sralph startpr(enable) 57812382Sralph { 57912382Sralph struct stat stbuf; 58012382Sralph 58112382Sralph bp = pbuf; 58212382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 58312382Sralph SD = DEFSPOOL; 58412382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 58512382Sralph LO = DEFLOCK; 58612382Sralph (void) sprintf(line, "%s/%s", SD, LO); 58712382Sralph printf("%s:\n", printer); 58812382Sralph 58912382Sralph /* 59012382Sralph * Turn off the owner execute bit of the lock file to enable printing. 59112382Sralph */ 59212382Sralph if (enable && stat(line, &stbuf) >= 0) { 59316771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 59412382Sralph printf("\tcannot enable printing\n"); 59512382Sralph else 59612382Sralph printf("\tprinting enabled\n"); 59712382Sralph } 59813727Sroot if (!startdaemon(printer)) 59912382Sralph printf("\tcouldn't start daemon\n"); 60012382Sralph else 60112382Sralph printf("\tdaemon started\n"); 60212382Sralph } 60312382Sralph 60412382Sralph /* 60512382Sralph * Print the status of each queue listed or all the queues. 60612382Sralph */ 60712382Sralph status(argc, argv) 60812382Sralph char *argv[]; 60912382Sralph { 61012382Sralph register int c, status; 61112382Sralph register char *cp1, *cp2; 61212382Sralph char prbuf[100]; 61312382Sralph 61412382Sralph if (argc == 1) { 61512382Sralph printer = prbuf; 61612382Sralph while (getprent(line) > 0) { 61712382Sralph cp1 = prbuf; 61812382Sralph cp2 = line; 61912382Sralph while ((c = *cp2++) && c != '|' && c != ':') 62012382Sralph *cp1++ = c; 62112382Sralph *cp1 = '\0'; 62212382Sralph prstat(); 62312382Sralph } 62412382Sralph return; 62512382Sralph } 62612382Sralph while (--argc) { 62712382Sralph printer = *++argv; 62812382Sralph if ((status = pgetent(line, printer)) < 0) { 62912514Sralph printf("cannot open printer description file\n"); 63012382Sralph continue; 63112382Sralph } else if (status == 0) { 63212514Sralph printf("unknown printer %s\n", printer); 63312382Sralph continue; 63412382Sralph } 63512382Sralph prstat(); 63612382Sralph } 63712382Sralph } 63812382Sralph 63912382Sralph /* 64012382Sralph * Print the status of the printer queue. 64112382Sralph */ 64212382Sralph prstat() 64312382Sralph { 64412382Sralph struct stat stbuf; 64512382Sralph register int fd, i; 64612382Sralph register struct direct *dp; 64712382Sralph DIR *dirp; 64812382Sralph 64912382Sralph bp = pbuf; 65012382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 65112382Sralph SD = DEFSPOOL; 65212382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 65312382Sralph LO = DEFLOCK; 65412382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 65512382Sralph ST = DEFSTAT; 65612382Sralph printf("%s:\n", printer); 65712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 65812382Sralph if (stat(line, &stbuf) >= 0) { 65912382Sralph printf("\tqueuing is %s\n", 66012382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 66112382Sralph printf("\tprinting is %s\n", 66212382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 66312382Sralph } else { 66412382Sralph printf("\tqueuing is enabled\n"); 66512382Sralph printf("\tprinting is enabled\n"); 66612382Sralph } 66712382Sralph if ((dirp = opendir(SD)) == NULL) { 66812382Sralph printf("\tcannot examine spool directory\n"); 66912382Sralph return; 67012382Sralph } 67112382Sralph i = 0; 67212382Sralph while ((dp = readdir(dirp)) != NULL) { 67312382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 67412382Sralph i++; 67512382Sralph } 67612382Sralph closedir(dirp); 67712382Sralph if (i == 0) 67812382Sralph printf("\tno entries\n"); 67912382Sralph else if (i == 1) 68012382Sralph printf("\t1 entry in spool area\n"); 68112382Sralph else 68212382Sralph printf("\t%d entries in spool area\n", i); 68313146Ssam fd = open(line, O_RDONLY); 68413146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 68513168Sralph (void) close(fd); /* unlocks as well */ 68612382Sralph printf("\tno daemon present\n"); 68712382Sralph return; 68812382Sralph } 68912382Sralph (void) close(fd); 69012382Sralph putchar('\t'); 69112382Sralph (void) sprintf(line, "%s/%s", SD, ST); 69213146Ssam fd = open(line, O_RDONLY); 69313146Ssam if (fd >= 0) { 69413146Ssam (void) flock(fd, LOCK_SH); 69512382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 69612382Sralph (void) fwrite(line, 1, i, stdout); 69713168Sralph (void) close(fd); /* unlocks as well */ 69812382Sralph } 69912382Sralph } 70012382Sralph 70112382Sralph /* 70212382Sralph * Stop the specified daemon after completing the current job and disable 70312382Sralph * printing. 70412382Sralph */ 70512382Sralph stop(argc, argv) 70612382Sralph char *argv[]; 70712382Sralph { 70812382Sralph register int c, status; 70912382Sralph register char *cp1, *cp2; 71012382Sralph char prbuf[100]; 71112382Sralph 71212382Sralph if (argc == 1) { 71312382Sralph printf("Usage: stop {all | printer ...}\n"); 71412382Sralph return; 71512382Sralph } 71612382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 71712382Sralph printer = prbuf; 71812382Sralph while (getprent(line) > 0) { 71912382Sralph cp1 = prbuf; 72012382Sralph cp2 = line; 72112382Sralph while ((c = *cp2++) && c != '|' && c != ':') 72212382Sralph *cp1++ = c; 72312382Sralph *cp1 = '\0'; 72412382Sralph stoppr(); 72512382Sralph } 72612382Sralph return; 72712382Sralph } 72812382Sralph while (--argc) { 72912382Sralph printer = *++argv; 73012382Sralph if ((status = pgetent(line, printer)) < 0) { 73112514Sralph printf("cannot open printer description file\n"); 73212382Sralph continue; 73312382Sralph } else if (status == 0) { 73412514Sralph printf("unknown printer %s\n", printer); 73512382Sralph continue; 73612382Sralph } 73712382Sralph stoppr(); 73812382Sralph } 73912382Sralph } 74012382Sralph 74112382Sralph stoppr() 74212382Sralph { 74312382Sralph register int fd; 74412382Sralph struct stat stbuf; 74512382Sralph 74612382Sralph bp = pbuf; 74712382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 74812382Sralph SD = DEFSPOOL; 74912382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 75012382Sralph LO = DEFLOCK; 75112382Sralph (void) sprintf(line, "%s/%s", SD, LO); 75212382Sralph printf("%s:\n", printer); 75312382Sralph 75412382Sralph /* 75512382Sralph * Turn on the owner execute bit of the lock file to disable printing. 75612382Sralph */ 75712382Sralph if (stat(line, &stbuf) >= 0) { 75812382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 75912382Sralph printf("\tcannot disable printing\n"); 76012382Sralph else 76112382Sralph printf("\tprinting disabled\n"); 76212382Sralph } else if (errno == ENOENT) { 76313146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 76412382Sralph printf("\tcannot create lock file\n"); 76512382Sralph else { 76612382Sralph (void) close(fd); 76712382Sralph printf("\tprinting disabled\n"); 76812382Sralph } 76912382Sralph } else 77012382Sralph printf("\tcannot stat lock file\n"); 77112382Sralph } 77213727Sroot 77315719Sralph struct queue **queue; 77415719Sralph int nitems; 77515719Sralph time_t mtime; 77615719Sralph 77713727Sroot /* 77813727Sroot * Put the specified jobs at the top of printer queue. 77913727Sroot */ 78013727Sroot topq(argc, argv) 78113727Sroot char *argv[]; 78213727Sroot { 78315719Sralph register int n, i; 78413727Sroot struct stat stbuf; 78513727Sroot register char *cfname; 78615719Sralph int status, changed; 78713727Sroot 78815719Sralph if (argc < 3) { 78913727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 79013727Sroot return; 79113727Sroot } 79213727Sroot 79313727Sroot --argc; 79413727Sroot printer = *++argv; 79513727Sroot status = pgetent(line, printer); 79613727Sroot if (status < 0) { 79713727Sroot printf("cannot open printer description file\n"); 79813727Sroot return; 79914151Sralph } else if (status == 0) { 80013727Sroot printf("%s: unknown printer\n", printer); 80113727Sroot return; 80213727Sroot } 80313727Sroot bp = pbuf; 80413727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 80513727Sroot SD = DEFSPOOL; 80613727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 80713727Sroot LO = DEFLOCK; 80813727Sroot printf("%s:\n", printer); 80913727Sroot 81013727Sroot if (chdir(SD) < 0) { 81113727Sroot printf("\tcannot chdir to %s\n", SD); 81213727Sroot return; 81313727Sroot } 81413727Sroot nitems = getq(&queue); 81515719Sralph if (nitems == 0) 81615719Sralph return; 81715719Sralph changed = 0; 81815719Sralph mtime = queue[0]->q_time; 81915719Sralph for (i = argc; --i; ) { 82015719Sralph if (doarg(argv[i]) == 0) { 82115719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 82213727Sroot continue; 82315719Sralph } else 82414151Sralph changed++; 82513727Sroot } 82615719Sralph for (i = 0; i < nitems; i++) 82715719Sralph free(queue[i]); 82815719Sralph free(queue); 82915719Sralph if (!changed) { 83015719Sralph printf("\tqueue order unchanged\n"); 83115719Sralph return; 83213727Sroot } 83313727Sroot /* 83413727Sroot * Turn on the public execute bit of the lock file to 83513727Sroot * get lpd to rebuild the queue after the current job. 83613727Sroot */ 83714151Sralph if (changed && stat(LO, &stbuf) >= 0) 83814151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 83913727Sroot } 84013727Sroot 84115719Sralph /* 84215719Sralph * Reposition the job by changing the modification time of 84315719Sralph * the control file. 84413727Sroot */ 84515719Sralph touch(q) 84615719Sralph struct queue *q; 84713727Sroot { 84815719Sralph struct timeval tvp[2]; 84913727Sroot 85015719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 85115719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 85215719Sralph return(utimes(q->q_name, tvp)); 85313727Sroot } 85413727Sroot 85513727Sroot /* 85613727Sroot * Checks if specified job name is in the printer's queue. 85713727Sroot * Returns: negative (-1) if argument name is not in the queue. 85813727Sroot */ 85915719Sralph doarg(job) 86013727Sroot char *job; 86113727Sroot { 86215719Sralph register struct queue **qq; 86315719Sralph register int jobnum, n; 86415719Sralph register char *cp, *machine; 86515719Sralph int cnt = 0; 86614151Sralph FILE *fp; 86713727Sroot 86815719Sralph /* 86915719Sralph * Look for a job item consisting of system name, colon, number 87015719Sralph * (example: ucbarpa:114) 87115719Sralph */ 87215719Sralph if ((cp = index(job, ':')) != NULL) { 87315719Sralph machine = job; 87415719Sralph *cp++ = '\0'; 87515719Sralph job = cp; 87615719Sralph } else 87715719Sralph machine = NULL; 87815719Sralph 87915719Sralph /* 88015719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 88115719Sralph */ 88213727Sroot if (isdigit(*job)) { 88313727Sroot jobnum = 0; 88413727Sroot do 88513727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 88613727Sroot while (isdigit(*job)); 88715719Sralph for (qq = queue + nitems; --qq >= queue; ) { 88813727Sroot n = 0; 88915719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 89014151Sralph n = n * 10 + (*cp++ - '0'); 89115719Sralph if (jobnum != n) 89215719Sralph continue; 89315719Sralph if (*job && strcmp(job, cp) != 0) 89415719Sralph continue; 89515719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 89615719Sralph continue; 89715719Sralph if (touch(*qq) == 0) { 89815719Sralph printf("\tmoved %s\n", (*qq)->q_name); 89915719Sralph cnt++; 90015719Sralph } 90113727Sroot } 90215719Sralph return(cnt); 90315719Sralph } 90415719Sralph /* 90515719Sralph * Process item consisting of owner's name (example: henry). 90615719Sralph */ 90715719Sralph for (qq = queue + nitems; --qq >= queue; ) { 90815719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 90913727Sroot continue; 91015719Sralph while (getline(fp) > 0) 91115719Sralph if (line[0] == 'P') 91215719Sralph break; 91315719Sralph (void) fclose(fp); 91415719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 91515719Sralph continue; 91615719Sralph if (touch(*qq) == 0) { 91715719Sralph printf("\tmoved %s\n", (*qq)->q_name); 91815719Sralph cnt++; 91913727Sroot } 92013727Sroot } 92115719Sralph return(cnt); 92213727Sroot } 92316755Sralph 92416755Sralph /* 92516755Sralph * Enable everything and start printer (undo `down'). 92616755Sralph */ 92716755Sralph up(argc, argv) 92816755Sralph char *argv[]; 92916755Sralph { 93016755Sralph register int c, status; 93116755Sralph register char *cp1, *cp2; 93216755Sralph char prbuf[100]; 93316755Sralph 93416755Sralph if (argc == 1) { 93516755Sralph printf("Usage: up {all | printer ...}\n"); 93616755Sralph return; 93716755Sralph } 93816755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 93916755Sralph printer = prbuf; 94016755Sralph while (getprent(line) > 0) { 94116755Sralph cp1 = prbuf; 94216755Sralph cp2 = line; 94316755Sralph while ((c = *cp2++) && c != '|' && c != ':') 94416755Sralph *cp1++ = c; 94516755Sralph *cp1 = '\0'; 94616755Sralph startpr(2); 94716755Sralph } 94816755Sralph return; 94916755Sralph } 95016755Sralph while (--argc) { 95116755Sralph printer = *++argv; 95216755Sralph if ((status = pgetent(line, printer)) < 0) { 95316755Sralph printf("cannot open printer description file\n"); 95416755Sralph continue; 95516755Sralph } else if (status == 0) { 95616755Sralph printf("unknown printer %s\n", printer); 95716755Sralph continue; 95816755Sralph } 95916755Sralph startpr(2); 96016755Sralph } 96116755Sralph } 962