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

unix.superglobalmegacorp.com

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