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

unix.superglobalmegacorp.com

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