1*22424Sdist /* 2*22424Sdist * Copyright (c) 1983 Regents of the University of California. 3*22424Sdist * All rights reserved. The Berkeley software License Agreement 4*22424Sdist * specifies the terms and conditions for redistribution. 5*22424Sdist */ 6*22424Sdist 712382Sralph #ifndef lint 8*22424Sdist static char sccsid[] = "@(#)cmds.c 5.1 (Berkeley) 06/06/85"; 9*22424Sdist #endif not lint 1012382Sralph 1112382Sralph /* 1215719Sralph * lpc -- line printer control program -- commands: 1312382Sralph */ 1412382Sralph 1512382Sralph #include "lp.h" 1615719Sralph #include <sys/time.h> 1712382Sralph 1812382Sralph /* 1912382Sralph * kill an existing daemon and disable printing. 2012382Sralph */ 2112382Sralph abort(argc, argv) 2212382Sralph char *argv[]; 2312382Sralph { 2412382Sralph register int c, status; 2512382Sralph register char *cp1, *cp2; 2612382Sralph char prbuf[100]; 2712382Sralph 2812382Sralph if (argc == 1) { 2912382Sralph printf("Usage: abort {all | printer ...}\n"); 3012382Sralph return; 3112382Sralph } 3212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 3312382Sralph printer = prbuf; 3412382Sralph while (getprent(line) > 0) { 3512382Sralph cp1 = prbuf; 3612382Sralph cp2 = line; 3712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 3812382Sralph *cp1++ = c; 3912382Sralph *cp1 = '\0'; 4016755Sralph abortpr(1); 4112382Sralph } 4212382Sralph return; 4312382Sralph } 4412382Sralph while (--argc) { 4512382Sralph printer = *++argv; 4612382Sralph if ((status = pgetent(line, printer)) < 0) { 4712514Sralph printf("cannot open printer description file\n"); 4812382Sralph continue; 4912382Sralph } else if (status == 0) { 5012514Sralph printf("unknown printer %s\n", printer); 5112382Sralph continue; 5212382Sralph } 5316755Sralph abortpr(1); 5412382Sralph } 5512382Sralph } 5612382Sralph 5716755Sralph abortpr(dis) 5812382Sralph { 5912382Sralph register FILE *fp; 6012382Sralph struct stat stbuf; 6112382Sralph int pid, fd; 6212382Sralph 6312382Sralph bp = pbuf; 6412382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 6512382Sralph SD = DEFSPOOL; 6612382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 6712382Sralph LO = DEFLOCK; 6812382Sralph (void) sprintf(line, "%s/%s", SD, LO); 6912382Sralph printf("%s:\n", printer); 7012382Sralph 7112382Sralph /* 7212382Sralph * Turn on the owner execute bit of the lock file to disable printing. 7312382Sralph */ 7416755Sralph if (dis) { 7516755Sralph if (stat(line, &stbuf) >= 0) { 7616755Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 7716755Sralph printf("\tcannot disable printing\n"); 7816755Sralph else 7916755Sralph printf("\tprinting disabled\n"); 8016755Sralph } else if (errno == ENOENT) { 8116755Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 8216755Sralph printf("\tcannot create lock file\n"); 8316755Sralph else { 8416755Sralph (void) close(fd); 8516755Sralph printf("\tprinting disabled\n"); 8616755Sralph printf("\tno daemon to abort\n"); 8716755Sralph } 8816755Sralph return; 8916755Sralph } else { 9016755Sralph printf("\tcannot stat lock file\n"); 9116755Sralph return; 9212382Sralph } 9312382Sralph } 9412382Sralph /* 9512382Sralph * Kill the current daemon to stop printing now. 9612382Sralph */ 9712382Sralph if ((fp = fopen(line, "r")) == NULL) { 9812382Sralph printf("\tcannot open lock file\n"); 9912382Sralph return; 10012382Sralph } 10113146Ssam if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 10213168Sralph (void) fclose(fp); /* unlocks as well */ 10312382Sralph printf("\tno daemon to abort\n"); 10412382Sralph return; 10512382Sralph } 10612382Sralph (void) fclose(fp); 10716755Sralph if (kill(pid = atoi(line), SIGTERM) < 0) 10812382Sralph printf("\tWarning: daemon (pid %d) not killed\n", pid); 10912382Sralph else 11012382Sralph printf("\tdaemon (pid %d) killed\n", pid); 11112382Sralph } 11212382Sralph 11312382Sralph /* 11412382Sralph * Remove all spool files and temporaries from the spooling area. 11512382Sralph */ 11612382Sralph clean(argc, argv) 11712382Sralph char *argv[]; 11812382Sralph { 11912382Sralph register int c, status; 12012382Sralph register char *cp1, *cp2; 12112382Sralph char prbuf[100]; 12212382Sralph 12312382Sralph if (argc == 1) { 12412382Sralph printf("Usage: clean {all | printer ...}\n"); 12512382Sralph return; 12612382Sralph } 12712382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 12812382Sralph printer = prbuf; 12912382Sralph while (getprent(line) > 0) { 13012382Sralph cp1 = prbuf; 13112382Sralph cp2 = line; 13212382Sralph while ((c = *cp2++) && c != '|' && c != ':') 13312382Sralph *cp1++ = c; 13412382Sralph *cp1 = '\0'; 13512382Sralph cleanpr(); 13612382Sralph } 13712382Sralph return; 13812382Sralph } 13912382Sralph while (--argc) { 14012382Sralph printer = *++argv; 14112382Sralph if ((status = pgetent(line, printer)) < 0) { 14212514Sralph printf("cannot open printer description file\n"); 14312382Sralph continue; 14412382Sralph } else if (status == 0) { 14512514Sralph printf("unknown printer %s\n", printer); 14612382Sralph continue; 14712382Sralph } 14812382Sralph cleanpr(); 14912382Sralph } 15012382Sralph } 15112382Sralph 15215719Sralph select(d) 15315719Sralph struct direct *d; 15415719Sralph { 15515719Sralph int c = d->d_name[0]; 15615719Sralph 15715719Sralph if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 15815719Sralph return(1); 15915719Sralph return(0); 16015719Sralph } 16115719Sralph 16215719Sralph /* 16315719Sralph * Comparison routine for scandir. Sort by job number and machine, then 16415719Sralph * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 16515719Sralph */ 16615719Sralph sortq(d1, d2) 16715719Sralph struct direct **d1, **d2; 16815719Sralph { 16915719Sralph int c1, c2; 17015719Sralph 17115719Sralph if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) 17215719Sralph return(c1); 17315719Sralph c1 = (*d1)->d_name[0]; 17415719Sralph c2 = (*d2)->d_name[0]; 17515719Sralph if (c1 == c2) 17615719Sralph return((*d1)->d_name[2] - (*d2)->d_name[2]); 17715719Sralph if (c1 == 'c') 17815719Sralph return(-1); 17915719Sralph if (c1 == 'd' || c2 == 'c') 18015719Sralph return(1); 18115719Sralph return(-1); 18215719Sralph } 18315719Sralph 18415719Sralph /* 18515719Sralph * Remove incomplete jobs from spooling area. 18615719Sralph */ 18712382Sralph cleanpr() 18812382Sralph { 18915719Sralph register int i, n; 19015719Sralph register char *cp, *cp1, *lp; 19115719Sralph struct direct **queue; 19215719Sralph int nitems; 19312382Sralph 19412382Sralph bp = pbuf; 19512382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 19612382Sralph SD = DEFSPOOL; 19712382Sralph printf("%s:\n", printer); 19812382Sralph 19915719Sralph for (lp = line, cp = SD; *lp++ = *cp++; ) 20015719Sralph ; 20115719Sralph lp[-1] = '/'; 20215719Sralph 20315719Sralph nitems = scandir(SD, &queue, select, sortq); 20415719Sralph if (nitems < 0) { 20512382Sralph printf("\tcannot examine spool directory\n"); 20612382Sralph return; 20712382Sralph } 20815719Sralph if (nitems == 0) 20915719Sralph return; 21015719Sralph i = 0; 21115719Sralph do { 21215719Sralph cp = queue[i]->d_name; 21315719Sralph if (*cp == 'c') { 21415719Sralph n = 0; 21515719Sralph while (i + 1 < nitems) { 21615719Sralph cp1 = queue[i + 1]->d_name; 21715719Sralph if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 21815719Sralph break; 21915719Sralph i++; 22015719Sralph n++; 22115719Sralph } 22215719Sralph if (n == 0) { 22315719Sralph strcpy(lp, cp); 22415719Sralph unlinkf(line); 22515719Sralph } 22615719Sralph } else { 22715719Sralph /* 22815719Sralph * Must be a df with no cf (otherwise, it would have 22915719Sralph * been skipped above) or a tf file (which can always 23015719Sralph * be removed). 23115719Sralph */ 23215719Sralph strcpy(lp, cp); 23315719Sralph unlinkf(line); 23412382Sralph } 23515719Sralph } while (++i < nitems); 23612382Sralph } 23715719Sralph 23815719Sralph unlinkf(name) 23915719Sralph char *name; 24015719Sralph { 24115719Sralph if (unlink(name) < 0) 24215719Sralph printf("\tcannot remove %s\n", name); 24315719Sralph else 24415719Sralph printf("\tremoved %s\n", name); 24515719Sralph } 24612382Sralph 24712382Sralph /* 24812382Sralph * Enable queuing to the printer (allow lpr's). 24912382Sralph */ 25012382Sralph enable(argc, argv) 25112382Sralph char *argv[]; 25212382Sralph { 25312382Sralph register int c, status; 25412382Sralph register char *cp1, *cp2; 25512382Sralph char prbuf[100]; 25612382Sralph 25712382Sralph if (argc == 1) { 25812382Sralph printf("Usage: enable {all | printer ...}\n"); 25912382Sralph return; 26012382Sralph } 26112382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 26212382Sralph printer = prbuf; 26312382Sralph while (getprent(line) > 0) { 26412382Sralph cp1 = prbuf; 26512382Sralph cp2 = line; 26612382Sralph while ((c = *cp2++) && c != '|' && c != ':') 26712382Sralph *cp1++ = c; 26812382Sralph *cp1 = '\0'; 26912382Sralph enablepr(); 27012382Sralph } 27112382Sralph return; 27212382Sralph } 27312382Sralph while (--argc) { 27412382Sralph printer = *++argv; 27512382Sralph if ((status = pgetent(line, printer)) < 0) { 27612514Sralph printf("cannot open printer description file\n"); 27712382Sralph continue; 27812382Sralph } else if (status == 0) { 27912514Sralph printf("unknown printer %s\n", printer); 28012382Sralph continue; 28112382Sralph } 28212382Sralph enablepr(); 28312382Sralph } 28412382Sralph } 28512382Sralph 28612382Sralph enablepr() 28712382Sralph { 28812382Sralph struct stat stbuf; 28912382Sralph 29012382Sralph bp = pbuf; 29112382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 29212382Sralph SD = DEFSPOOL; 29312382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 29412382Sralph LO = DEFLOCK; 29512382Sralph (void) sprintf(line, "%s/%s", SD, LO); 29612382Sralph printf("%s:\n", printer); 29712382Sralph 29812382Sralph /* 29912382Sralph * Turn off the group execute bit of the lock file to enable queuing. 30012382Sralph */ 30112382Sralph if (stat(line, &stbuf) >= 0) { 30212382Sralph if (chmod(line, stbuf.st_mode & 0767) < 0) 30312514Sralph printf("\tcannot enable queuing\n"); 30412382Sralph else 30512382Sralph printf("\tqueuing enabled\n"); 30612382Sralph } 30712382Sralph } 30812382Sralph 30912382Sralph /* 31012382Sralph * Disable queuing. 31112382Sralph */ 31212382Sralph disable(argc, argv) 31312382Sralph char *argv[]; 31412382Sralph { 31512382Sralph register int c, status; 31612382Sralph register char *cp1, *cp2; 31712382Sralph char prbuf[100]; 31812382Sralph 31912382Sralph if (argc == 1) { 32012382Sralph printf("Usage: disable {all | printer ...}\n"); 32112382Sralph return; 32212382Sralph } 32312382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 32412382Sralph printer = prbuf; 32512382Sralph while (getprent(line) > 0) { 32612382Sralph cp1 = prbuf; 32712382Sralph cp2 = line; 32812382Sralph while ((c = *cp2++) && c != '|' && c != ':') 32912382Sralph *cp1++ = c; 33012382Sralph *cp1 = '\0'; 33112382Sralph disablepr(); 33212382Sralph } 33312382Sralph return; 33412382Sralph } 33512382Sralph while (--argc) { 33612382Sralph printer = *++argv; 33712382Sralph if ((status = pgetent(line, printer)) < 0) { 33812514Sralph printf("cannot open printer description file\n"); 33912382Sralph continue; 34012382Sralph } else if (status == 0) { 34112514Sralph printf("unknown printer %s\n", printer); 34212382Sralph continue; 34312382Sralph } 34412382Sralph disablepr(); 34512382Sralph } 34612382Sralph } 34712382Sralph 34812382Sralph disablepr() 34912382Sralph { 35012382Sralph register int fd; 35112382Sralph struct stat stbuf; 35212382Sralph 35312382Sralph bp = pbuf; 35412382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 35512382Sralph SD = DEFSPOOL; 35612382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 35712382Sralph LO = DEFLOCK; 35812382Sralph (void) sprintf(line, "%s/%s", SD, LO); 35912382Sralph printf("%s:\n", printer); 36012382Sralph /* 36112382Sralph * Turn on the group execute bit of the lock file to disable queuing. 36212382Sralph */ 36312382Sralph if (stat(line, &stbuf) >= 0) { 36412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 36512382Sralph printf("\tcannot disable queuing\n"); 36612382Sralph else 36712382Sralph printf("\tqueuing disabled\n"); 36812382Sralph } else if (errno == ENOENT) { 36913146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 37012382Sralph printf("\tcannot create lock file\n"); 37112382Sralph else { 37212382Sralph (void) close(fd); 37312382Sralph printf("\tqueuing disabled\n"); 37412382Sralph } 37512382Sralph return; 37612382Sralph } else 37712382Sralph printf("\tcannot stat lock file\n"); 37812382Sralph } 37912382Sralph 38012382Sralph /* 38115907Sralph * Disable queuing and printing and put a message into the status file 38215907Sralph * (reason for being down). 38315907Sralph */ 38415907Sralph down(argc, argv) 38515907Sralph char *argv[]; 38615907Sralph { 38715907Sralph register int c, status; 38815907Sralph register char *cp1, *cp2; 38915907Sralph char prbuf[100]; 39015907Sralph 39115907Sralph if (argc == 1) { 39216204Sralph printf("Usage: down {all | printer} [message ...]\n"); 39315907Sralph return; 39415907Sralph } 39515907Sralph if (!strcmp(argv[1], "all")) { 39615907Sralph printer = prbuf; 39715907Sralph while (getprent(line) > 0) { 39815907Sralph cp1 = prbuf; 39915907Sralph cp2 = line; 40015907Sralph while ((c = *cp2++) && c != '|' && c != ':') 40115907Sralph *cp1++ = c; 40215907Sralph *cp1 = '\0'; 40315907Sralph putmsg(argc - 2, argv + 2); 40415907Sralph } 40515907Sralph return; 40615907Sralph } 40715907Sralph printer = argv[1]; 40815907Sralph if ((status = pgetent(line, printer)) < 0) { 40915907Sralph printf("cannot open printer description file\n"); 41015907Sralph return; 41115907Sralph } else if (status == 0) { 41215907Sralph printf("unknown printer %s\n", printer); 41315907Sralph return; 41415907Sralph } 41515907Sralph putmsg(argc - 2, argv + 2); 41615907Sralph } 41715907Sralph 41815907Sralph putmsg(argc, argv) 41915907Sralph char **argv; 42015907Sralph { 42115907Sralph register int fd; 42215907Sralph register char *cp1, *cp2; 42315907Sralph char buf[1024]; 42415907Sralph struct stat stbuf; 42515907Sralph 42615907Sralph bp = pbuf; 42715907Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 42815907Sralph SD = DEFSPOOL; 42915907Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 43015907Sralph LO = DEFLOCK; 43115907Sralph if ((ST = pgetstr("st", &bp)) == NULL) 43215907Sralph ST = DEFSTAT; 43315907Sralph printf("%s:\n", printer); 43415907Sralph /* 43515907Sralph * Turn on the group execute bit of the lock file to disable queuing and 43615907Sralph * turn on the owner execute bit of the lock file to disable printing. 43715907Sralph */ 43815907Sralph (void) sprintf(line, "%s/%s", SD, LO); 43915907Sralph if (stat(line, &stbuf) >= 0) { 44015907Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 44115907Sralph printf("\tcannot disable queuing\n"); 44215907Sralph else 44315907Sralph printf("\tprinter and queuing disabled\n"); 44415907Sralph } else if (errno == ENOENT) { 44515907Sralph if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 44615907Sralph printf("\tcannot create lock file\n"); 44715907Sralph else { 44815907Sralph (void) close(fd); 44915907Sralph printf("\tprinter and queuing disabled\n"); 45015907Sralph } 45115907Sralph return; 45215907Sralph } else 45315907Sralph printf("\tcannot stat lock file\n"); 45415907Sralph /* 45515907Sralph * Write the message into the status file. 45615907Sralph */ 45715907Sralph (void) sprintf(line, "%s/%s", SD, ST); 45815907Sralph fd = open(line, O_WRONLY|O_CREAT, 0664); 45915907Sralph if (fd < 0 || flock(fd, LOCK_EX) < 0) { 46015907Sralph printf("\tcannot create status file\n"); 46115907Sralph return; 46215907Sralph } 46315907Sralph (void) ftruncate(fd, 0); 46416204Sralph if (argc <= 0) { 46516204Sralph (void) write(fd, "\n", 1); 46616204Sralph (void) close(fd); 46716204Sralph return; 46816204Sralph } 46915907Sralph cp1 = buf; 47015907Sralph while (--argc >= 0) { 47115907Sralph cp2 = *argv++; 47215907Sralph while (*cp1++ = *cp2++) 47315907Sralph ; 47415907Sralph cp1[-1] = ' '; 47515907Sralph } 47615907Sralph cp1[-1] = '\n'; 47715907Sralph *cp1 = '\0'; 47815907Sralph (void) write(fd, buf, strlen(buf)); 47915907Sralph (void) close(fd); 48015907Sralph } 48115907Sralph 48215907Sralph /* 48312382Sralph * Exit lpc 48412382Sralph */ 48512382Sralph quit(argc, argv) 48612382Sralph char *argv[]; 48712382Sralph { 48812382Sralph exit(0); 48912382Sralph } 49012382Sralph 49112382Sralph /* 49216755Sralph * Kill and restart the daemon. 49312382Sralph */ 49412382Sralph restart(argc, argv) 49512382Sralph char *argv[]; 49612382Sralph { 49712382Sralph register int c, status; 49812382Sralph register char *cp1, *cp2; 49912382Sralph char prbuf[100]; 50012382Sralph 50112382Sralph if (argc == 1) { 50212382Sralph printf("Usage: restart {all | printer ...}\n"); 50312382Sralph return; 50412382Sralph } 50512382Sralph gethostname(host, sizeof(host)); 50612382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 50712382Sralph printer = prbuf; 50812382Sralph while (getprent(line) > 0) { 50912382Sralph cp1 = prbuf; 51012382Sralph cp2 = line; 51112382Sralph while ((c = *cp2++) && c != '|' && c != ':') 51212382Sralph *cp1++ = c; 51312382Sralph *cp1 = '\0'; 51416755Sralph abortpr(0); 51512382Sralph startpr(0); 51612382Sralph } 51712382Sralph return; 51812382Sralph } 51912382Sralph while (--argc) { 52012382Sralph printer = *++argv; 52112382Sralph if ((status = pgetent(line, printer)) < 0) { 52212514Sralph printf("cannot open printer description file\n"); 52312382Sralph continue; 52412382Sralph } else if (status == 0) { 52512514Sralph printf("unknown printer %s\n", printer); 52612382Sralph continue; 52712382Sralph } 52816755Sralph abortpr(0); 52912382Sralph startpr(0); 53012382Sralph } 53112382Sralph } 53212382Sralph 53312382Sralph /* 53412382Sralph * Enable printing on the specified printer and startup the daemon. 53512382Sralph */ 53612382Sralph start(argc, argv) 53712382Sralph char *argv[]; 53812382Sralph { 53912382Sralph register int c, status; 54012382Sralph register char *cp1, *cp2; 54112382Sralph char prbuf[100]; 54212382Sralph 54312382Sralph if (argc == 1) { 54412382Sralph printf("Usage: start {all | printer ...}\n"); 54512382Sralph return; 54612382Sralph } 54712382Sralph gethostname(host, sizeof(host)); 54812382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 54912382Sralph printer = prbuf; 55012382Sralph while (getprent(line) > 0) { 55112382Sralph cp1 = prbuf; 55212382Sralph cp2 = line; 55312382Sralph while ((c = *cp2++) && c != '|' && c != ':') 55412382Sralph *cp1++ = c; 55512382Sralph *cp1 = '\0'; 55612382Sralph startpr(1); 55712382Sralph } 55812382Sralph return; 55912382Sralph } 56012382Sralph while (--argc) { 56112382Sralph printer = *++argv; 56212382Sralph if ((status = pgetent(line, printer)) < 0) { 56312514Sralph printf("cannot open printer description file\n"); 56412382Sralph continue; 56512382Sralph } else if (status == 0) { 56612514Sralph printf("unknown printer %s\n", printer); 56712382Sralph continue; 56812382Sralph } 56912382Sralph startpr(1); 57012382Sralph } 57112382Sralph } 57212382Sralph 57312382Sralph startpr(enable) 57412382Sralph { 57512382Sralph struct stat stbuf; 57612382Sralph 57712382Sralph bp = pbuf; 57812382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 57912382Sralph SD = DEFSPOOL; 58012382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 58112382Sralph LO = DEFLOCK; 58212382Sralph (void) sprintf(line, "%s/%s", SD, LO); 58312382Sralph printf("%s:\n", printer); 58412382Sralph 58512382Sralph /* 58612382Sralph * Turn off the owner execute bit of the lock file to enable printing. 58712382Sralph */ 58812382Sralph if (enable && stat(line, &stbuf) >= 0) { 58916771Sralph if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 59012382Sralph printf("\tcannot enable printing\n"); 59112382Sralph else 59212382Sralph printf("\tprinting enabled\n"); 59312382Sralph } 59413727Sroot if (!startdaemon(printer)) 59512382Sralph printf("\tcouldn't start daemon\n"); 59612382Sralph else 59712382Sralph printf("\tdaemon started\n"); 59812382Sralph } 59912382Sralph 60012382Sralph /* 60112382Sralph * Print the status of each queue listed or all the queues. 60212382Sralph */ 60312382Sralph status(argc, argv) 60412382Sralph char *argv[]; 60512382Sralph { 60612382Sralph register int c, status; 60712382Sralph register char *cp1, *cp2; 60812382Sralph char prbuf[100]; 60912382Sralph 61012382Sralph if (argc == 1) { 61112382Sralph printer = prbuf; 61212382Sralph while (getprent(line) > 0) { 61312382Sralph cp1 = prbuf; 61412382Sralph cp2 = line; 61512382Sralph while ((c = *cp2++) && c != '|' && c != ':') 61612382Sralph *cp1++ = c; 61712382Sralph *cp1 = '\0'; 61812382Sralph prstat(); 61912382Sralph } 62012382Sralph return; 62112382Sralph } 62212382Sralph while (--argc) { 62312382Sralph printer = *++argv; 62412382Sralph if ((status = pgetent(line, printer)) < 0) { 62512514Sralph printf("cannot open printer description file\n"); 62612382Sralph continue; 62712382Sralph } else if (status == 0) { 62812514Sralph printf("unknown printer %s\n", printer); 62912382Sralph continue; 63012382Sralph } 63112382Sralph prstat(); 63212382Sralph } 63312382Sralph } 63412382Sralph 63512382Sralph /* 63612382Sralph * Print the status of the printer queue. 63712382Sralph */ 63812382Sralph prstat() 63912382Sralph { 64012382Sralph struct stat stbuf; 64112382Sralph register int fd, i; 64212382Sralph register struct direct *dp; 64312382Sralph DIR *dirp; 64412382Sralph 64512382Sralph bp = pbuf; 64612382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 64712382Sralph SD = DEFSPOOL; 64812382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 64912382Sralph LO = DEFLOCK; 65012382Sralph if ((ST = pgetstr("st", &bp)) == NULL) 65112382Sralph ST = DEFSTAT; 65212382Sralph printf("%s:\n", printer); 65312382Sralph (void) sprintf(line, "%s/%s", SD, LO); 65412382Sralph if (stat(line, &stbuf) >= 0) { 65512382Sralph printf("\tqueuing is %s\n", 65612382Sralph (stbuf.st_mode & 010) ? "disabled" : "enabled"); 65712382Sralph printf("\tprinting is %s\n", 65812382Sralph (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 65912382Sralph } else { 66012382Sralph printf("\tqueuing is enabled\n"); 66112382Sralph printf("\tprinting is enabled\n"); 66212382Sralph } 66312382Sralph if ((dirp = opendir(SD)) == NULL) { 66412382Sralph printf("\tcannot examine spool directory\n"); 66512382Sralph return; 66612382Sralph } 66712382Sralph i = 0; 66812382Sralph while ((dp = readdir(dirp)) != NULL) { 66912382Sralph if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 67012382Sralph i++; 67112382Sralph } 67212382Sralph closedir(dirp); 67312382Sralph if (i == 0) 67412382Sralph printf("\tno entries\n"); 67512382Sralph else if (i == 1) 67612382Sralph printf("\t1 entry in spool area\n"); 67712382Sralph else 67812382Sralph printf("\t%d entries in spool area\n", i); 67913146Ssam fd = open(line, O_RDONLY); 68013146Ssam if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 68113168Sralph (void) close(fd); /* unlocks as well */ 68212382Sralph printf("\tno daemon present\n"); 68312382Sralph return; 68412382Sralph } 68512382Sralph (void) close(fd); 68612382Sralph putchar('\t'); 68712382Sralph (void) sprintf(line, "%s/%s", SD, ST); 68813146Ssam fd = open(line, O_RDONLY); 68913146Ssam if (fd >= 0) { 69013146Ssam (void) flock(fd, LOCK_SH); 69112382Sralph while ((i = read(fd, line, sizeof(line))) > 0) 69212382Sralph (void) fwrite(line, 1, i, stdout); 69313168Sralph (void) close(fd); /* unlocks as well */ 69412382Sralph } 69512382Sralph } 69612382Sralph 69712382Sralph /* 69812382Sralph * Stop the specified daemon after completing the current job and disable 69912382Sralph * printing. 70012382Sralph */ 70112382Sralph stop(argc, argv) 70212382Sralph char *argv[]; 70312382Sralph { 70412382Sralph register int c, status; 70512382Sralph register char *cp1, *cp2; 70612382Sralph char prbuf[100]; 70712382Sralph 70812382Sralph if (argc == 1) { 70912382Sralph printf("Usage: stop {all | printer ...}\n"); 71012382Sralph return; 71112382Sralph } 71212382Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 71312382Sralph printer = prbuf; 71412382Sralph while (getprent(line) > 0) { 71512382Sralph cp1 = prbuf; 71612382Sralph cp2 = line; 71712382Sralph while ((c = *cp2++) && c != '|' && c != ':') 71812382Sralph *cp1++ = c; 71912382Sralph *cp1 = '\0'; 72012382Sralph stoppr(); 72112382Sralph } 72212382Sralph return; 72312382Sralph } 72412382Sralph while (--argc) { 72512382Sralph printer = *++argv; 72612382Sralph if ((status = pgetent(line, printer)) < 0) { 72712514Sralph printf("cannot open printer description file\n"); 72812382Sralph continue; 72912382Sralph } else if (status == 0) { 73012514Sralph printf("unknown printer %s\n", printer); 73112382Sralph continue; 73212382Sralph } 73312382Sralph stoppr(); 73412382Sralph } 73512382Sralph } 73612382Sralph 73712382Sralph stoppr() 73812382Sralph { 73912382Sralph register int fd; 74012382Sralph struct stat stbuf; 74112382Sralph 74212382Sralph bp = pbuf; 74312382Sralph if ((SD = pgetstr("sd", &bp)) == NULL) 74412382Sralph SD = DEFSPOOL; 74512382Sralph if ((LO = pgetstr("lo", &bp)) == NULL) 74612382Sralph LO = DEFLOCK; 74712382Sralph (void) sprintf(line, "%s/%s", SD, LO); 74812382Sralph printf("%s:\n", printer); 74912382Sralph 75012382Sralph /* 75112382Sralph * Turn on the owner execute bit of the lock file to disable printing. 75212382Sralph */ 75312382Sralph if (stat(line, &stbuf) >= 0) { 75412382Sralph if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 75512382Sralph printf("\tcannot disable printing\n"); 75612382Sralph else 75712382Sralph printf("\tprinting disabled\n"); 75812382Sralph } else if (errno == ENOENT) { 75913146Ssam if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 76012382Sralph printf("\tcannot create lock file\n"); 76112382Sralph else { 76212382Sralph (void) close(fd); 76312382Sralph printf("\tprinting disabled\n"); 76412382Sralph } 76512382Sralph } else 76612382Sralph printf("\tcannot stat lock file\n"); 76712382Sralph } 76813727Sroot 76915719Sralph struct queue **queue; 77015719Sralph int nitems; 77115719Sralph time_t mtime; 77215719Sralph 77313727Sroot /* 77413727Sroot * Put the specified jobs at the top of printer queue. 77513727Sroot */ 77613727Sroot topq(argc, argv) 77713727Sroot char *argv[]; 77813727Sroot { 77915719Sralph register int n, i; 78013727Sroot struct stat stbuf; 78113727Sroot register char *cfname; 78215719Sralph int status, changed; 78313727Sroot 78415719Sralph if (argc < 3) { 78513727Sroot printf("Usage: topq printer [jobnum ...] [user ...]\n"); 78613727Sroot return; 78713727Sroot } 78813727Sroot 78913727Sroot --argc; 79013727Sroot printer = *++argv; 79113727Sroot status = pgetent(line, printer); 79213727Sroot if (status < 0) { 79313727Sroot printf("cannot open printer description file\n"); 79413727Sroot return; 79514151Sralph } else if (status == 0) { 79613727Sroot printf("%s: unknown printer\n", printer); 79713727Sroot return; 79813727Sroot } 79913727Sroot bp = pbuf; 80013727Sroot if ((SD = pgetstr("sd", &bp)) == NULL) 80113727Sroot SD = DEFSPOOL; 80213727Sroot if ((LO = pgetstr("lo", &bp)) == NULL) 80313727Sroot LO = DEFLOCK; 80413727Sroot printf("%s:\n", printer); 80513727Sroot 80613727Sroot if (chdir(SD) < 0) { 80713727Sroot printf("\tcannot chdir to %s\n", SD); 80813727Sroot return; 80913727Sroot } 81013727Sroot nitems = getq(&queue); 81115719Sralph if (nitems == 0) 81215719Sralph return; 81315719Sralph changed = 0; 81415719Sralph mtime = queue[0]->q_time; 81515719Sralph for (i = argc; --i; ) { 81615719Sralph if (doarg(argv[i]) == 0) { 81715719Sralph printf("\tjob %s is not in the queue\n", argv[i]); 81813727Sroot continue; 81915719Sralph } else 82014151Sralph changed++; 82113727Sroot } 82215719Sralph for (i = 0; i < nitems; i++) 82315719Sralph free(queue[i]); 82415719Sralph free(queue); 82515719Sralph if (!changed) { 82615719Sralph printf("\tqueue order unchanged\n"); 82715719Sralph return; 82813727Sroot } 82913727Sroot /* 83013727Sroot * Turn on the public execute bit of the lock file to 83113727Sroot * get lpd to rebuild the queue after the current job. 83213727Sroot */ 83314151Sralph if (changed && stat(LO, &stbuf) >= 0) 83414151Sralph (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 83513727Sroot } 83613727Sroot 83715719Sralph /* 83815719Sralph * Reposition the job by changing the modification time of 83915719Sralph * the control file. 84013727Sroot */ 84115719Sralph touch(q) 84215719Sralph struct queue *q; 84313727Sroot { 84415719Sralph struct timeval tvp[2]; 84513727Sroot 84615719Sralph tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 84715719Sralph tvp[0].tv_usec = tvp[1].tv_usec = 0; 84815719Sralph return(utimes(q->q_name, tvp)); 84913727Sroot } 85013727Sroot 85113727Sroot /* 85213727Sroot * Checks if specified job name is in the printer's queue. 85313727Sroot * Returns: negative (-1) if argument name is not in the queue. 85413727Sroot */ 85515719Sralph doarg(job) 85613727Sroot char *job; 85713727Sroot { 85815719Sralph register struct queue **qq; 85915719Sralph register int jobnum, n; 86015719Sralph register char *cp, *machine; 86115719Sralph int cnt = 0; 86214151Sralph FILE *fp; 86313727Sroot 86415719Sralph /* 86515719Sralph * Look for a job item consisting of system name, colon, number 86615719Sralph * (example: ucbarpa:114) 86715719Sralph */ 86815719Sralph if ((cp = index(job, ':')) != NULL) { 86915719Sralph machine = job; 87015719Sralph *cp++ = '\0'; 87115719Sralph job = cp; 87215719Sralph } else 87315719Sralph machine = NULL; 87415719Sralph 87515719Sralph /* 87615719Sralph * Check for job specified by number (example: 112 or 235ucbarpa). 87715719Sralph */ 87813727Sroot if (isdigit(*job)) { 87913727Sroot jobnum = 0; 88013727Sroot do 88113727Sroot jobnum = jobnum * 10 + (*job++ - '0'); 88213727Sroot while (isdigit(*job)); 88315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 88413727Sroot n = 0; 88515719Sralph for (cp = (*qq)->q_name+3; isdigit(*cp); ) 88614151Sralph n = n * 10 + (*cp++ - '0'); 88715719Sralph if (jobnum != n) 88815719Sralph continue; 88915719Sralph if (*job && strcmp(job, cp) != 0) 89015719Sralph continue; 89115719Sralph if (machine != NULL && strcmp(machine, cp) != 0) 89215719Sralph continue; 89315719Sralph if (touch(*qq) == 0) { 89415719Sralph printf("\tmoved %s\n", (*qq)->q_name); 89515719Sralph cnt++; 89615719Sralph } 89713727Sroot } 89815719Sralph return(cnt); 89915719Sralph } 90015719Sralph /* 90115719Sralph * Process item consisting of owner's name (example: henry). 90215719Sralph */ 90315719Sralph for (qq = queue + nitems; --qq >= queue; ) { 90415719Sralph if ((fp = fopen((*qq)->q_name, "r")) == NULL) 90513727Sroot continue; 90615719Sralph while (getline(fp) > 0) 90715719Sralph if (line[0] == 'P') 90815719Sralph break; 90915719Sralph (void) fclose(fp); 91015719Sralph if (line[0] != 'P' || strcmp(job, line+1) != 0) 91115719Sralph continue; 91215719Sralph if (touch(*qq) == 0) { 91315719Sralph printf("\tmoved %s\n", (*qq)->q_name); 91415719Sralph cnt++; 91513727Sroot } 91613727Sroot } 91715719Sralph return(cnt); 91813727Sroot } 91916755Sralph 92016755Sralph /* 92116755Sralph * Enable everything and start printer (undo `down'). 92216755Sralph */ 92316755Sralph up(argc, argv) 92416755Sralph char *argv[]; 92516755Sralph { 92616755Sralph register int c, status; 92716755Sralph register char *cp1, *cp2; 92816755Sralph char prbuf[100]; 92916755Sralph 93016755Sralph if (argc == 1) { 93116755Sralph printf("Usage: up {all | printer ...}\n"); 93216755Sralph return; 93316755Sralph } 93416755Sralph if (argc == 2 && !strcmp(argv[1], "all")) { 93516755Sralph printer = prbuf; 93616755Sralph while (getprent(line) > 0) { 93716755Sralph cp1 = prbuf; 93816755Sralph cp2 = line; 93916755Sralph while ((c = *cp2++) && c != '|' && c != ':') 94016755Sralph *cp1++ = c; 94116755Sralph *cp1 = '\0'; 94216755Sralph startpr(2); 94316755Sralph } 94416755Sralph return; 94516755Sralph } 94616755Sralph while (--argc) { 94716755Sralph printer = *++argv; 94816755Sralph if ((status = pgetent(line, printer)) < 0) { 94916755Sralph printf("cannot open printer description file\n"); 95016755Sralph continue; 95116755Sralph } else if (status == 0) { 95216755Sralph printf("unknown printer %s\n", printer); 95316755Sralph continue; 95416755Sralph } 95516755Sralph startpr(2); 95616755Sralph } 95716755Sralph } 958