Annotation of 43BSD/usr.lib/lpr/cmds.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)cmds.c     5.2 (Berkeley) 3/30/86";
                      9: #endif not lint
                     10: 
                     11: /*
                     12:  * lpc -- line printer control program -- commands:
                     13:  */
                     14: 
                     15: #include "lp.h"
                     16: #include <sys/time.h>
                     17: 
                     18: /*
                     19:  * kill an existing daemon and disable printing.
                     20:  */
                     21: abort(argc, argv)
                     22:        char *argv[];
                     23: {
                     24:        register int c, status;
                     25:        register char *cp1, *cp2;
                     26:        char prbuf[100];
                     27: 
                     28:        if (argc == 1) {
                     29:                printf("Usage: abort {all | printer ...}\n");
                     30:                return;
                     31:        }
                     32:        if (argc == 2 && !strcmp(argv[1], "all")) {
                     33:                printer = prbuf;
                     34:                while (getprent(line) > 0) {
                     35:                        cp1 = prbuf;
                     36:                        cp2 = line;
                     37:                        while ((c = *cp2++) && c != '|' && c != ':')
                     38:                                *cp1++ = c;
                     39:                        *cp1 = '\0';
                     40:                        abortpr(1);
                     41:                }
                     42:                return;
                     43:        }
                     44:        while (--argc) {
                     45:                printer = *++argv;
                     46:                if ((status = pgetent(line, printer)) < 0) {
                     47:                        printf("cannot open printer description file\n");
                     48:                        continue;
                     49:                } else if (status == 0) {
                     50:                        printf("unknown printer %s\n", printer);
                     51:                        continue;
                     52:                }
                     53:                abortpr(1);
                     54:        }
                     55: }
                     56: 
                     57: abortpr(dis)
                     58: {
                     59:        register FILE *fp;
                     60:        struct stat stbuf;
                     61:        int pid, fd;
                     62: 
                     63:        bp = pbuf;
                     64:        if ((SD = pgetstr("sd", &bp)) == NULL)
                     65:                SD = DEFSPOOL;
                     66:        if ((LO = pgetstr("lo", &bp)) == NULL)
                     67:                LO = DEFLOCK;
                     68:        (void) sprintf(line, "%s/%s", SD, LO);
                     69:        printf("%s:\n", printer);
                     70: 
                     71:        /*
                     72:         * Turn on the owner execute bit of the lock file to disable printing.
                     73:         */
                     74:        if (dis) {
                     75:                if (stat(line, &stbuf) >= 0) {
                     76:                        if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
                     77:                                printf("\tcannot disable printing\n");
                     78:                        else
                     79:                                printf("\tprinting disabled\n");
                     80:                } else if (errno == ENOENT) {
                     81:                        if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
                     82:                                printf("\tcannot create lock file\n");
                     83:                        else {
                     84:                                (void) close(fd);
                     85:                                printf("\tprinting disabled\n");
                     86:                                printf("\tno daemon to abort\n");
                     87:                        }
                     88:                        return;
                     89:                } else {
                     90:                        printf("\tcannot stat lock file\n");
                     91:                        return;
                     92:                }
                     93:        }
                     94:        /*
                     95:         * Kill the current daemon to stop printing now.
                     96:         */
                     97:        if ((fp = fopen(line, "r")) == NULL) {
                     98:                printf("\tcannot open lock file\n");
                     99:                return;
                    100:        }
                    101:        if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
                    102:                (void) fclose(fp);      /* unlocks as well */
                    103:                printf("\tno daemon to abort\n");
                    104:                return;
                    105:        }
                    106:        (void) fclose(fp);
                    107:        if (kill(pid = atoi(line), SIGTERM) < 0)
                    108:                printf("\tWarning: daemon (pid %d) not killed\n", pid);
                    109:        else
                    110:                printf("\tdaemon (pid %d) killed\n", pid);
                    111: }
                    112: 
                    113: /*
                    114:  * Remove all spool files and temporaries from the spooling area.
                    115:  */
                    116: clean(argc, argv)
                    117:        char *argv[];
                    118: {
                    119:        register int c, status;
                    120:        register char *cp1, *cp2;
                    121:        char prbuf[100];
                    122: 
                    123:        if (argc == 1) {
                    124:                printf("Usage: clean {all | printer ...}\n");
                    125:                return;
                    126:        }
                    127:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    128:                printer = prbuf;
                    129:                while (getprent(line) > 0) {
                    130:                        cp1 = prbuf;
                    131:                        cp2 = line;
                    132:                        while ((c = *cp2++) && c != '|' && c != ':')
                    133:                                *cp1++ = c;
                    134:                        *cp1 = '\0';
                    135:                        cleanpr();
                    136:                }
                    137:                return;
                    138:        }
                    139:        while (--argc) {
                    140:                printer = *++argv;
                    141:                if ((status = pgetent(line, printer)) < 0) {
                    142:                        printf("cannot open printer description file\n");
                    143:                        continue;
                    144:                } else if (status == 0) {
                    145:                        printf("unknown printer %s\n", printer);
                    146:                        continue;
                    147:                }
                    148:                cleanpr();
                    149:        }
                    150: }
                    151: 
                    152: select(d)
                    153: struct direct *d;
                    154: {
                    155:        int c = d->d_name[0];
                    156: 
                    157:        if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
                    158:                return(1);
                    159:        return(0);
                    160: }
                    161: 
                    162: /*
                    163:  * Comparison routine for scandir. Sort by job number and machine, then
                    164:  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
                    165:  */
                    166: sortq(d1, d2)
                    167: struct direct **d1, **d2;
                    168: {
                    169:        int c1, c2;
                    170: 
                    171:        if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
                    172:                return(c1);
                    173:        c1 = (*d1)->d_name[0];
                    174:        c2 = (*d2)->d_name[0];
                    175:        if (c1 == c2)
                    176:                return((*d1)->d_name[2] - (*d2)->d_name[2]);
                    177:        if (c1 == 'c')
                    178:                return(-1);
                    179:        if (c1 == 'd' || c2 == 'c')
                    180:                return(1);
                    181:        return(-1);
                    182: }
                    183: 
                    184: /*
                    185:  * Remove incomplete jobs from spooling area.
                    186:  */
                    187: cleanpr()
                    188: {
                    189:        register int i, n;
                    190:        register char *cp, *cp1, *lp;
                    191:        struct direct **queue;
                    192:        int nitems;
                    193: 
                    194:        bp = pbuf;
                    195:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    196:                SD = DEFSPOOL;
                    197:        printf("%s:\n", printer);
                    198: 
                    199:        for (lp = line, cp = SD; *lp++ = *cp++; )
                    200:                ;
                    201:        lp[-1] = '/';
                    202: 
                    203:        nitems = scandir(SD, &queue, select, sortq);
                    204:        if (nitems < 0) {
                    205:                printf("\tcannot examine spool directory\n");
                    206:                return;
                    207:        }
                    208:        if (nitems == 0)
                    209:                return;
                    210:        i = 0;
                    211:        do {
                    212:                cp = queue[i]->d_name;
                    213:                if (*cp == 'c') {
                    214:                        n = 0;
                    215:                        while (i + 1 < nitems) {
                    216:                                cp1 = queue[i + 1]->d_name;
                    217:                                if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
                    218:                                        break;
                    219:                                i++;
                    220:                                n++;
                    221:                        }
                    222:                        if (n == 0) {
                    223:                                strcpy(lp, cp);
                    224:                                unlinkf(line);
                    225:                        }
                    226:                } else {
                    227:                        /*
                    228:                         * Must be a df with no cf (otherwise, it would have
                    229:                         * been skipped above) or a tf file (which can always
                    230:                         * be removed).
                    231:                         */
                    232:                        strcpy(lp, cp);
                    233:                        unlinkf(line);
                    234:                }
                    235:        } while (++i < nitems);
                    236: }
                    237:  
                    238: unlinkf(name)
                    239:        char    *name;
                    240: {
                    241:        if (unlink(name) < 0)
                    242:                printf("\tcannot remove %s\n", name);
                    243:        else
                    244:                printf("\tremoved %s\n", name);
                    245: }
                    246: 
                    247: /*
                    248:  * Enable queuing to the printer (allow lpr's).
                    249:  */
                    250: enable(argc, argv)
                    251:        char *argv[];
                    252: {
                    253:        register int c, status;
                    254:        register char *cp1, *cp2;
                    255:        char prbuf[100];
                    256: 
                    257:        if (argc == 1) {
                    258:                printf("Usage: enable {all | printer ...}\n");
                    259:                return;
                    260:        }
                    261:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    262:                printer = prbuf;
                    263:                while (getprent(line) > 0) {
                    264:                        cp1 = prbuf;
                    265:                        cp2 = line;
                    266:                        while ((c = *cp2++) && c != '|' && c != ':')
                    267:                                *cp1++ = c;
                    268:                        *cp1 = '\0';
                    269:                        enablepr();
                    270:                }
                    271:                return;
                    272:        }
                    273:        while (--argc) {
                    274:                printer = *++argv;
                    275:                if ((status = pgetent(line, printer)) < 0) {
                    276:                        printf("cannot open printer description file\n");
                    277:                        continue;
                    278:                } else if (status == 0) {
                    279:                        printf("unknown printer %s\n", printer);
                    280:                        continue;
                    281:                }
                    282:                enablepr();
                    283:        }
                    284: }
                    285: 
                    286: enablepr()
                    287: {
                    288:        struct stat stbuf;
                    289: 
                    290:        bp = pbuf;
                    291:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    292:                SD = DEFSPOOL;
                    293:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    294:                LO = DEFLOCK;
                    295:        (void) sprintf(line, "%s/%s", SD, LO);
                    296:        printf("%s:\n", printer);
                    297: 
                    298:        /*
                    299:         * Turn off the group execute bit of the lock file to enable queuing.
                    300:         */
                    301:        if (stat(line, &stbuf) >= 0) {
                    302:                if (chmod(line, stbuf.st_mode & 0767) < 0)
                    303:                        printf("\tcannot enable queuing\n");
                    304:                else
                    305:                        printf("\tqueuing enabled\n");
                    306:        }
                    307: }
                    308: 
                    309: /*
                    310:  * Disable queuing.
                    311:  */
                    312: disable(argc, argv)
                    313:        char *argv[];
                    314: {
                    315:        register int c, status;
                    316:        register char *cp1, *cp2;
                    317:        char prbuf[100];
                    318: 
                    319:        if (argc == 1) {
                    320:                printf("Usage: disable {all | printer ...}\n");
                    321:                return;
                    322:        }
                    323:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    324:                printer = prbuf;
                    325:                while (getprent(line) > 0) {
                    326:                        cp1 = prbuf;
                    327:                        cp2 = line;
                    328:                        while ((c = *cp2++) && c != '|' && c != ':')
                    329:                                *cp1++ = c;
                    330:                        *cp1 = '\0';
                    331:                        disablepr();
                    332:                }
                    333:                return;
                    334:        }
                    335:        while (--argc) {
                    336:                printer = *++argv;
                    337:                if ((status = pgetent(line, printer)) < 0) {
                    338:                        printf("cannot open printer description file\n");
                    339:                        continue;
                    340:                } else if (status == 0) {
                    341:                        printf("unknown printer %s\n", printer);
                    342:                        continue;
                    343:                }
                    344:                disablepr();
                    345:        }
                    346: }
                    347: 
                    348: disablepr()
                    349: {
                    350:        register int fd;
                    351:        struct stat stbuf;
                    352: 
                    353:        bp = pbuf;
                    354:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    355:                SD = DEFSPOOL;
                    356:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    357:                LO = DEFLOCK;
                    358:        (void) sprintf(line, "%s/%s", SD, LO);
                    359:        printf("%s:\n", printer);
                    360:        /*
                    361:         * Turn on the group execute bit of the lock file to disable queuing.
                    362:         */
                    363:        if (stat(line, &stbuf) >= 0) {
                    364:                if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
                    365:                        printf("\tcannot disable queuing\n");
                    366:                else
                    367:                        printf("\tqueuing disabled\n");
                    368:        } else if (errno == ENOENT) {
                    369:                if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
                    370:                        printf("\tcannot create lock file\n");
                    371:                else {
                    372:                        (void) close(fd);
                    373:                        printf("\tqueuing disabled\n");
                    374:                }
                    375:                return;
                    376:        } else
                    377:                printf("\tcannot stat lock file\n");
                    378: }
                    379: 
                    380: /*
                    381:  * Disable queuing and printing and put a message into the status file
                    382:  * (reason for being down).
                    383:  */
                    384: down(argc, argv)
                    385:        char *argv[];
                    386: {
                    387:        register int c, status;
                    388:        register char *cp1, *cp2;
                    389:        char prbuf[100];
                    390: 
                    391:        if (argc == 1) {
                    392:                printf("Usage: down {all | printer} [message ...]\n");
                    393:                return;
                    394:        }
                    395:        if (!strcmp(argv[1], "all")) {
                    396:                printer = prbuf;
                    397:                while (getprent(line) > 0) {
                    398:                        cp1 = prbuf;
                    399:                        cp2 = line;
                    400:                        while ((c = *cp2++) && c != '|' && c != ':')
                    401:                                *cp1++ = c;
                    402:                        *cp1 = '\0';
                    403:                        putmsg(argc - 2, argv + 2);
                    404:                }
                    405:                return;
                    406:        }
                    407:        printer = argv[1];
                    408:        if ((status = pgetent(line, printer)) < 0) {
                    409:                printf("cannot open printer description file\n");
                    410:                return;
                    411:        } else if (status == 0) {
                    412:                printf("unknown printer %s\n", printer);
                    413:                return;
                    414:        }
                    415:        putmsg(argc - 2, argv + 2);
                    416: }
                    417: 
                    418: putmsg(argc, argv)
                    419:        char **argv;
                    420: {
                    421:        register int fd;
                    422:        register char *cp1, *cp2;
                    423:        char buf[1024];
                    424:        struct stat stbuf;
                    425: 
                    426:        bp = pbuf;
                    427:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    428:                SD = DEFSPOOL;
                    429:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    430:                LO = DEFLOCK;
                    431:        if ((ST = pgetstr("st", &bp)) == NULL)
                    432:                ST = DEFSTAT;
                    433:        printf("%s:\n", printer);
                    434:        /*
                    435:         * Turn on the group execute bit of the lock file to disable queuing and
                    436:         * turn on the owner execute bit of the lock file to disable printing.
                    437:         */
                    438:        (void) sprintf(line, "%s/%s", SD, LO);
                    439:        if (stat(line, &stbuf) >= 0) {
                    440:                if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
                    441:                        printf("\tcannot disable queuing\n");
                    442:                else
                    443:                        printf("\tprinter and queuing disabled\n");
                    444:        } else if (errno == ENOENT) {
                    445:                if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
                    446:                        printf("\tcannot create lock file\n");
                    447:                else {
                    448:                        (void) close(fd);
                    449:                        printf("\tprinter and queuing disabled\n");
                    450:                }
                    451:                return;
                    452:        } else
                    453:                printf("\tcannot stat lock file\n");
                    454:        /*
                    455:         * Write the message into the status file.
                    456:         */
                    457:        (void) sprintf(line, "%s/%s", SD, ST);
                    458:        fd = open(line, O_WRONLY|O_CREAT, 0664);
                    459:        if (fd < 0 || flock(fd, LOCK_EX) < 0) {
                    460:                printf("\tcannot create status file\n");
                    461:                return;
                    462:        }
                    463:        (void) ftruncate(fd, 0);
                    464:        if (argc <= 0) {
                    465:                (void) write(fd, "\n", 1);
                    466:                (void) close(fd);
                    467:                return;
                    468:        }
                    469:        cp1 = buf;
                    470:        while (--argc >= 0) {
                    471:                cp2 = *argv++;
                    472:                while (*cp1++ = *cp2++)
                    473:                        ;
                    474:                cp1[-1] = ' ';
                    475:        }
                    476:        cp1[-1] = '\n';
                    477:        *cp1 = '\0';
                    478:        (void) write(fd, buf, strlen(buf));
                    479:        (void) close(fd);
                    480: }
                    481: 
                    482: /*
                    483:  * Exit lpc
                    484:  */
                    485: quit(argc, argv)
                    486:        char *argv[];
                    487: {
                    488:        exit(0);
                    489: }
                    490: 
                    491: /*
                    492:  * Kill and restart the daemon.
                    493:  */
                    494: restart(argc, argv)
                    495:        char *argv[];
                    496: {
                    497:        register int c, status;
                    498:        register char *cp1, *cp2;
                    499:        char prbuf[100];
                    500: 
                    501:        if (argc == 1) {
                    502:                printf("Usage: restart {all | printer ...}\n");
                    503:                return;
                    504:        }
                    505:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    506:                printer = prbuf;
                    507:                while (getprent(line) > 0) {
                    508:                        cp1 = prbuf;
                    509:                        cp2 = line;
                    510:                        while ((c = *cp2++) && c != '|' && c != ':')
                    511:                                *cp1++ = c;
                    512:                        *cp1 = '\0';
                    513:                        abortpr(0);
                    514:                        startpr(0);
                    515:                }
                    516:                return;
                    517:        }
                    518:        while (--argc) {
                    519:                printer = *++argv;
                    520:                if ((status = pgetent(line, printer)) < 0) {
                    521:                        printf("cannot open printer description file\n");
                    522:                        continue;
                    523:                } else if (status == 0) {
                    524:                        printf("unknown printer %s\n", printer);
                    525:                        continue;
                    526:                }
                    527:                abortpr(0);
                    528:                startpr(0);
                    529:        }
                    530: }
                    531: 
                    532: /*
                    533:  * Enable printing on the specified printer and startup the daemon.
                    534:  */
                    535: start(argc, argv)
                    536:        char *argv[];
                    537: {
                    538:        register int c, status;
                    539:        register char *cp1, *cp2;
                    540:        char prbuf[100];
                    541: 
                    542:        if (argc == 1) {
                    543:                printf("Usage: start {all | printer ...}\n");
                    544:                return;
                    545:        }
                    546:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    547:                printer = prbuf;
                    548:                while (getprent(line) > 0) {
                    549:                        cp1 = prbuf;
                    550:                        cp2 = line;
                    551:                        while ((c = *cp2++) && c != '|' && c != ':')
                    552:                                *cp1++ = c;
                    553:                        *cp1 = '\0';
                    554:                        startpr(1);
                    555:                }
                    556:                return;
                    557:        }
                    558:        while (--argc) {
                    559:                printer = *++argv;
                    560:                if ((status = pgetent(line, printer)) < 0) {
                    561:                        printf("cannot open printer description file\n");
                    562:                        continue;
                    563:                } else if (status == 0) {
                    564:                        printf("unknown printer %s\n", printer);
                    565:                        continue;
                    566:                }
                    567:                startpr(1);
                    568:        }
                    569: }
                    570: 
                    571: startpr(enable)
                    572: {
                    573:        struct stat stbuf;
                    574: 
                    575:        bp = pbuf;
                    576:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    577:                SD = DEFSPOOL;
                    578:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    579:                LO = DEFLOCK;
                    580:        (void) sprintf(line, "%s/%s", SD, LO);
                    581:        printf("%s:\n", printer);
                    582: 
                    583:        /*
                    584:         * Turn off the owner execute bit of the lock file to enable printing.
                    585:         */
                    586:        if (enable && stat(line, &stbuf) >= 0) {
                    587:                if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
                    588:                        printf("\tcannot enable printing\n");
                    589:                else
                    590:                        printf("\tprinting enabled\n");
                    591:        }
                    592:        if (!startdaemon(printer))
                    593:                printf("\tcouldn't start daemon\n");
                    594:        else
                    595:                printf("\tdaemon started\n");
                    596: }
                    597: 
                    598: /*
                    599:  * Print the status of each queue listed or all the queues.
                    600:  */
                    601: status(argc, argv)
                    602:        char *argv[];
                    603: {
                    604:        register int c, status;
                    605:        register char *cp1, *cp2;
                    606:        char prbuf[100];
                    607: 
                    608:        if (argc == 1) {
                    609:                printer = prbuf;
                    610:                while (getprent(line) > 0) {
                    611:                        cp1 = prbuf;
                    612:                        cp2 = line;
                    613:                        while ((c = *cp2++) && c != '|' && c != ':')
                    614:                                *cp1++ = c;
                    615:                        *cp1 = '\0';
                    616:                        prstat();
                    617:                }
                    618:                return;
                    619:        }
                    620:        while (--argc) {
                    621:                printer = *++argv;
                    622:                if ((status = pgetent(line, printer)) < 0) {
                    623:                        printf("cannot open printer description file\n");
                    624:                        continue;
                    625:                } else if (status == 0) {
                    626:                        printf("unknown printer %s\n", printer);
                    627:                        continue;
                    628:                }
                    629:                prstat();
                    630:        }
                    631: }
                    632: 
                    633: /*
                    634:  * Print the status of the printer queue.
                    635:  */
                    636: prstat()
                    637: {
                    638:        struct stat stbuf;
                    639:        register int fd, i;
                    640:        register struct direct *dp;
                    641:        DIR *dirp;
                    642: 
                    643:        bp = pbuf;
                    644:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    645:                SD = DEFSPOOL;
                    646:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    647:                LO = DEFLOCK;
                    648:        if ((ST = pgetstr("st", &bp)) == NULL)
                    649:                ST = DEFSTAT;
                    650:        printf("%s:\n", printer);
                    651:        (void) sprintf(line, "%s/%s", SD, LO);
                    652:        if (stat(line, &stbuf) >= 0) {
                    653:                printf("\tqueuing is %s\n",
                    654:                        (stbuf.st_mode & 010) ? "disabled" : "enabled");
                    655:                printf("\tprinting is %s\n",
                    656:                        (stbuf.st_mode & 0100) ? "disabled" : "enabled");
                    657:        } else {
                    658:                printf("\tqueuing is enabled\n");
                    659:                printf("\tprinting is enabled\n");
                    660:        }
                    661:        if ((dirp = opendir(SD)) == NULL) {
                    662:                printf("\tcannot examine spool directory\n");
                    663:                return;
                    664:        }
                    665:        i = 0;
                    666:        while ((dp = readdir(dirp)) != NULL) {
                    667:                if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
                    668:                        i++;
                    669:        }
                    670:        closedir(dirp);
                    671:        if (i == 0)
                    672:                printf("\tno entries\n");
                    673:        else if (i == 1)
                    674:                printf("\t1 entry in spool area\n");
                    675:        else
                    676:                printf("\t%d entries in spool area\n", i);
                    677:        fd = open(line, O_RDONLY);
                    678:        if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
                    679:                (void) close(fd);       /* unlocks as well */
                    680:                printf("\tno daemon present\n");
                    681:                return;
                    682:        }
                    683:        (void) close(fd);
                    684:        putchar('\t');
                    685:        (void) sprintf(line, "%s/%s", SD, ST);
                    686:        fd = open(line, O_RDONLY);
                    687:        if (fd >= 0) {
                    688:                (void) flock(fd, LOCK_SH);
                    689:                while ((i = read(fd, line, sizeof(line))) > 0)
                    690:                        (void) fwrite(line, 1, i, stdout);
                    691:                (void) close(fd);       /* unlocks as well */
                    692:        }
                    693: }
                    694: 
                    695: /*
                    696:  * Stop the specified daemon after completing the current job and disable
                    697:  * printing.
                    698:  */
                    699: stop(argc, argv)
                    700:        char *argv[];
                    701: {
                    702:        register int c, status;
                    703:        register char *cp1, *cp2;
                    704:        char prbuf[100];
                    705: 
                    706:        if (argc == 1) {
                    707:                printf("Usage: stop {all | printer ...}\n");
                    708:                return;
                    709:        }
                    710:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    711:                printer = prbuf;
                    712:                while (getprent(line) > 0) {
                    713:                        cp1 = prbuf;
                    714:                        cp2 = line;
                    715:                        while ((c = *cp2++) && c != '|' && c != ':')
                    716:                                *cp1++ = c;
                    717:                        *cp1 = '\0';
                    718:                        stoppr();
                    719:                }
                    720:                return;
                    721:        }
                    722:        while (--argc) {
                    723:                printer = *++argv;
                    724:                if ((status = pgetent(line, printer)) < 0) {
                    725:                        printf("cannot open printer description file\n");
                    726:                        continue;
                    727:                } else if (status == 0) {
                    728:                        printf("unknown printer %s\n", printer);
                    729:                        continue;
                    730:                }
                    731:                stoppr();
                    732:        }
                    733: }
                    734: 
                    735: stoppr()
                    736: {
                    737:        register int fd;
                    738:        struct stat stbuf;
                    739: 
                    740:        bp = pbuf;
                    741:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    742:                SD = DEFSPOOL;
                    743:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    744:                LO = DEFLOCK;
                    745:        (void) sprintf(line, "%s/%s", SD, LO);
                    746:        printf("%s:\n", printer);
                    747: 
                    748:        /*
                    749:         * Turn on the owner execute bit of the lock file to disable printing.
                    750:         */
                    751:        if (stat(line, &stbuf) >= 0) {
                    752:                if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
                    753:                        printf("\tcannot disable printing\n");
                    754:                else
                    755:                        printf("\tprinting disabled\n");
                    756:        } else if (errno == ENOENT) {
                    757:                if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
                    758:                        printf("\tcannot create lock file\n");
                    759:                else {
                    760:                        (void) close(fd);
                    761:                        printf("\tprinting disabled\n");
                    762:                }
                    763:        } else
                    764:                printf("\tcannot stat lock file\n");
                    765: }
                    766: 
                    767: struct queue **queue;
                    768: int    nitems;
                    769: time_t mtime;
                    770: 
                    771: /*
                    772:  * Put the specified jobs at the top of printer queue.
                    773:  */
                    774: topq(argc, argv)
                    775:        char *argv[];
                    776: {
                    777:        register int n, i;
                    778:        struct stat stbuf;
                    779:        register char *cfname;
                    780:        int status, changed;
                    781: 
                    782:        if (argc < 3) {
                    783:                printf("Usage: topq printer [jobnum ...] [user ...]\n");
                    784:                return;
                    785:        }
                    786: 
                    787:        --argc;
                    788:        printer = *++argv;
                    789:        status = pgetent(line, printer);
                    790:        if (status < 0) {
                    791:                printf("cannot open printer description file\n");
                    792:                return;
                    793:        } else if (status == 0) {
                    794:                printf("%s: unknown printer\n", printer);
                    795:                return;
                    796:        }
                    797:        bp = pbuf;
                    798:        if ((SD = pgetstr("sd", &bp)) == NULL)
                    799:                SD = DEFSPOOL;
                    800:        if ((LO = pgetstr("lo", &bp)) == NULL)
                    801:                LO = DEFLOCK;
                    802:        printf("%s:\n", printer);
                    803: 
                    804:        if (chdir(SD) < 0) {
                    805:                printf("\tcannot chdir to %s\n", SD);
                    806:                return;
                    807:        }
                    808:        nitems = getq(&queue);
                    809:        if (nitems == 0)
                    810:                return;
                    811:        changed = 0;
                    812:        mtime = queue[0]->q_time;
                    813:        for (i = argc; --i; ) {
                    814:                if (doarg(argv[i]) == 0) {
                    815:                        printf("\tjob %s is not in the queue\n", argv[i]);
                    816:                        continue;
                    817:                } else
                    818:                        changed++;
                    819:        }
                    820:        for (i = 0; i < nitems; i++)
                    821:                free(queue[i]);
                    822:        free(queue);
                    823:        if (!changed) {
                    824:                printf("\tqueue order unchanged\n");
                    825:                return;
                    826:        }
                    827:        /*
                    828:         * Turn on the public execute bit of the lock file to
                    829:         * get lpd to rebuild the queue after the current job.
                    830:         */
                    831:        if (changed && stat(LO, &stbuf) >= 0)
                    832:                (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
                    833: } 
                    834: 
                    835: /*
                    836:  * Reposition the job by changing the modification time of
                    837:  * the control file.
                    838:  */
                    839: touch(q)
                    840:        struct queue *q;
                    841: {
                    842:        struct timeval tvp[2];
                    843: 
                    844:        tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
                    845:        tvp[0].tv_usec = tvp[1].tv_usec = 0;
                    846:        return(utimes(q->q_name, tvp));
                    847: }
                    848: 
                    849: /*
                    850:  * Checks if specified job name is in the printer's queue.
                    851:  * Returns:  negative (-1) if argument name is not in the queue.
                    852:  */
                    853: doarg(job)
                    854:        char *job;
                    855: {
                    856:        register struct queue **qq;
                    857:        register int jobnum, n;
                    858:        register char *cp, *machine;
                    859:        int cnt = 0;
                    860:        FILE *fp;
                    861: 
                    862:        /*
                    863:         * Look for a job item consisting of system name, colon, number 
                    864:         * (example: ucbarpa:114)  
                    865:         */
                    866:        if ((cp = index(job, ':')) != NULL) {
                    867:                machine = job;
                    868:                *cp++ = '\0';
                    869:                job = cp;
                    870:        } else
                    871:                machine = NULL;
                    872: 
                    873:        /*
                    874:         * Check for job specified by number (example: 112 or 235ucbarpa).
                    875:         */
                    876:        if (isdigit(*job)) {
                    877:                jobnum = 0;
                    878:                do
                    879:                        jobnum = jobnum * 10 + (*job++ - '0');
                    880:                while (isdigit(*job));
                    881:                for (qq = queue + nitems; --qq >= queue; ) {
                    882:                        n = 0;
                    883:                        for (cp = (*qq)->q_name+3; isdigit(*cp); )
                    884:                                n = n * 10 + (*cp++ - '0');
                    885:                        if (jobnum != n)
                    886:                                continue;
                    887:                        if (*job && strcmp(job, cp) != 0)
                    888:                                continue;
                    889:                        if (machine != NULL && strcmp(machine, cp) != 0)
                    890:                                continue;
                    891:                        if (touch(*qq) == 0) {
                    892:                                printf("\tmoved %s\n", (*qq)->q_name);
                    893:                                cnt++;
                    894:                        }
                    895:                }
                    896:                return(cnt);
                    897:        }
                    898:        /*
                    899:         * Process item consisting of owner's name (example: henry).
                    900:         */
                    901:        for (qq = queue + nitems; --qq >= queue; ) {
                    902:                if ((fp = fopen((*qq)->q_name, "r")) == NULL)
                    903:                        continue;
                    904:                while (getline(fp) > 0)
                    905:                        if (line[0] == 'P')
                    906:                                break;
                    907:                (void) fclose(fp);
                    908:                if (line[0] != 'P' || strcmp(job, line+1) != 0)
                    909:                        continue;
                    910:                if (touch(*qq) == 0) {
                    911:                        printf("\tmoved %s\n", (*qq)->q_name);
                    912:                        cnt++;
                    913:                }
                    914:        }
                    915:        return(cnt);
                    916: }
                    917: 
                    918: /*
                    919:  * Enable everything and start printer (undo `down').
                    920:  */
                    921: up(argc, argv)
                    922:        char *argv[];
                    923: {
                    924:        register int c, status;
                    925:        register char *cp1, *cp2;
                    926:        char prbuf[100];
                    927: 
                    928:        if (argc == 1) {
                    929:                printf("Usage: up {all | printer ...}\n");
                    930:                return;
                    931:        }
                    932:        if (argc == 2 && !strcmp(argv[1], "all")) {
                    933:                printer = prbuf;
                    934:                while (getprent(line) > 0) {
                    935:                        cp1 = prbuf;
                    936:                        cp2 = line;
                    937:                        while ((c = *cp2++) && c != '|' && c != ':')
                    938:                                *cp1++ = c;
                    939:                        *cp1 = '\0';
                    940:                        startpr(2);
                    941:                }
                    942:                return;
                    943:        }
                    944:        while (--argc) {
                    945:                printer = *++argv;
                    946:                if ((status = pgetent(line, printer)) < 0) {
                    947:                        printf("cannot open printer description file\n");
                    948:                        continue;
                    949:                } else if (status == 0) {
                    950:                        printf("unknown printer %s\n", printer);
                    951:                        continue;
                    952:                }
                    953:                startpr(2);
                    954:        }
                    955: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.