Annotation of 42BSD/ucb/man.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)man.c      1.10 (Berkeley) 9/19/83";
                      3: #endif
                      4: 
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include <sgtty.h>
                      8: #include <sys/types.h>
                      9: #include <sys/stat.h>
                     10: #include <signal.h>
                     11: /*
                     12:  * man
                     13:  * link also to apropos and whatis
                     14:  * This version uses more for underlining and paging.
                     15:  */
                     16: #define        MANDIR  "/usr/man"              /* this is deeply embedded */
                     17: #define        NROFFCAT "nroff -h -man"        /* for nroffing to cat file */
                     18: #define        NROFF   "nroff -man"            /* for nroffing to tty */
                     19: #define        MORE    "more -s"               /* paging filter */
                     20: #define        CAT     "cat -s"                /* for '-' opt (no more) */
                     21: 
                     22: #define TROFFCMD \
                     23: "troff -t -man /usr/lib/tmac/tmac.vcat %s | /usr/lib/rvsort |/usr/ucb/vpr -t"
                     24: 
                     25: /*  for troff:
                     26: #define        TROFFCMD "troff -man %s"
                     27: */
                     28: 
                     29: #define        ALLSECT "1nl6823457po"  /* order to look through sections */
                     30: #define        SECT1   "1nlo"          /* sections to look at if 1 is specified */
                     31: #define        SUBSEC1 "mcgprv"        /* subsections to try in section 1 */
                     32: #define        SUBSEC2 "v"
                     33: #define        SUBSEC3 "jxmsnvcf"
                     34: #define        SUBSEC4 "pfvsn"
                     35: #define        SUBSEC8 "vc"
                     36: 
                     37: int    nomore;
                     38: int    cflag;
                     39: char   *manpath = "/usr/man";
                     40: char   *strcpy();
                     41: char   *strcat();
                     42: char   *trim();
                     43: int    remove();
                     44: int    section;
                     45: int    subsec;
                     46: int    troffit;
                     47: int    killtmp;
                     48: 
                     49: #define        eq(a,b) (strcmp(a,b) == 0)
                     50: 
                     51: main(argc, argv)
                     52:        int argc;
                     53:        char *argv[];
                     54: {
                     55: 
                     56:        if (signal(SIGINT, SIG_IGN) == SIG_DFL) {
                     57:                signal(SIGINT, remove);
                     58:                signal(SIGQUIT, remove);
                     59:                signal(SIGTERM, remove);
                     60:        }
                     61:        umask(0);
                     62:        if (strcmp(argv[0], "apropos") == 0) {
                     63:                apropos(argc-1, argv+1);
                     64:                exit(0);
                     65:        }
                     66:        if (strcmp(argv[0], "whatis") == 0) {
                     67:                whatis(argc-1, argv+1);
                     68:                exit(0);
                     69:        }
                     70:        if (argc <= 1) {
                     71:                fprintf(stderr, "Usage: man [ section ] name ...\n");
                     72:                exit(1);
                     73:        }
                     74:        argc--, argv++;
                     75:        while (argc > 0 && argv[0][0] == '-') {
                     76:                switch(argv[0][1]) {
                     77: 
                     78:                case 0:
                     79:                        nomore++;
                     80:                        break;
                     81: 
                     82:                case 't':
                     83:                        troffit++;
                     84:                        break;
                     85: 
                     86:                case 'k':
                     87:                        apropos(argc-1, argv+1);
                     88:                        exit(0);
                     89: 
                     90:                case 'f':
                     91:                        whatis(argc-1, argv+1);
                     92:                        exit(0);
                     93: 
                     94:                case 'P':
                     95:                        argc--, argv++;
                     96:                        manpath = *argv;
                     97:                        break;
                     98:                }
                     99:                argc--, argv++;
                    100:        }
                    101:        if (chdir(manpath) < 0) {
                    102:                fprintf(stderr, "Can't chdir to %s.\n", manpath);
                    103:                exit(1);
                    104:        }
                    105:        if (troffit == 0 && nomore == 0 && !isatty(1))
                    106:                nomore++;
                    107:        section = 0;
                    108:        do {
                    109:                if (eq(argv[0], "local")) {
                    110:                        section = 'l';
                    111:                        goto sectin;
                    112:                } else if (eq(argv[0], "new")) {
                    113:                        section = 'n';
                    114:                        goto sectin;
                    115:                } else if (eq(argv[0], "old")) {
                    116:                        section = 'o';
                    117:                        goto sectin;
                    118:                } else if (eq(argv[0], "public")) {
                    119:                        section = 'p';
                    120:                        goto sectin;
                    121:                } else if (argv[0][0] >= '0' && argv[0][0] <= '9' && (argv[0][1] == 0 || argv[0][2] == 0)) {
                    122:                        section = argv[0][0];
                    123:                        subsec = argv[0][1];
                    124: sectin:
                    125:                        argc--, argv++;
                    126:                        if (argc == 0) {
                    127:                                fprintf(stderr, "But what do you want from section %s?\n", argv[-1]);
                    128:                                exit(1);
                    129:                        }
                    130:                        continue;
                    131:                }
                    132:                manual(section, argv[0]);
                    133:                argc--, argv++;
                    134:        } while (argc > 0);
                    135:        exit(0);
                    136: }
                    137: 
                    138: manual(sec, name)
                    139:        char sec;
                    140:        char *name;
                    141: {
                    142:        char section = sec;
                    143:        char work[100], work2[100], cmdbuf[150];
                    144:        int ss;
                    145:        struct stat stbuf, stbuf2;
                    146:        int last;
                    147:        char *sp = ALLSECT;
                    148: 
                    149:        strcpy(work, "manx/");
                    150:        strcat(work, name);
                    151:        strcat(work, ".x");
                    152:        last = strlen(work) - 1;
                    153:        if (section == '1') {
                    154:                sp = SECT1;
                    155:                section = 0;
                    156:        }
                    157:        if (section == 0) {
                    158:                ss = 0;
                    159:                for (section = *sp++; section; section = *sp++) {
                    160:                        work[3] = section;
                    161:                        work[last] = section;
                    162:                        work[last+1] = 0;
                    163:                        work[last+2] = 0;
                    164:                        if (stat(work, &stbuf) >= 0)
                    165:                                break;
                    166:                        if (work[last] >= '1' && work[last] <= '8') {
                    167:                                char *cp;
                    168: search:
                    169:                                switch (work[last]) {
                    170:                                case '1': cp = SUBSEC1; break;
                    171:                                case '2': cp = SUBSEC2; break;
                    172:                                case '3': cp = SUBSEC3; break;
                    173:                                case '4': cp = SUBSEC4; break;
                    174:                                case '8': cp = SUBSEC8; break;
                    175:                                }
                    176:                                while (*cp) {
                    177:                                        work[last+1] = *cp++;
                    178:                                        if (stat(work, &stbuf) >= 0) {
                    179:                                                ss = work[last+1];
                    180:                                                goto found;
                    181:                                        }
                    182:                                }
                    183:                                if (ss = 0)
                    184:                                        work[last+1] = 0;
                    185:                        }
                    186:                }
                    187:                if (section == 0) {
                    188:                        if (sec == 0)
                    189:                                printf("No manual entry for %s.\n", name);
                    190:                        else
                    191:                                printf("No entry for %s in section %c of the manual.\n", name, sec);
                    192:                        return;
                    193:                }
                    194:        } else {
                    195:                work[3] = section;
                    196:                work[last] = section;
                    197:                work[last+1] = subsec;
                    198:                work[last+2] = 0;
                    199:                if (stat(work, &stbuf) < 0) {
                    200:                        if ((section >= '1' && section <= '8') && subsec == 0) {
                    201:                                sp = "\0";
                    202:                                goto search;
                    203:                        }
                    204:                        printf("No entry for %s in section %c", name, section);
                    205:                        if (subsec)
                    206:                                putchar(subsec);
                    207:                        printf(" of the manual.\n");
                    208:                        return;
                    209:                }
                    210:        }
                    211: found:
                    212:        if (troffit)
                    213:                troff(work);
                    214:        else {
                    215:                FILE *it;
                    216:                char abuf[BUFSIZ];
                    217: 
                    218:                if (!nomore) {
                    219:                        if ((it = fopen(work, "r")) == NULL) {
                    220:                                perror(work);
                    221:                                exit(1);
                    222:                        }
                    223:                        if (fgets(abuf, BUFSIZ-1, it) &&
                    224:                           abuf[0] == '.' && abuf[1] == 's' &&
                    225:                           abuf[2] == 'o' && abuf[3] == ' ') {
                    226:                                register char *cp = abuf+strlen(".so ");
                    227:                                char *dp;
                    228: 
                    229:                                while (*cp && *cp != '\n')
                    230:                                        cp++;
                    231:                                *cp = 0;
                    232:                                while (cp > abuf && *--cp != '/')
                    233:                                        ;
                    234:                                dp = ".so man";
                    235:                                if (cp != abuf+strlen(dp)+1) {
                    236: tohard:
                    237:                                        nomore = 1;
                    238:                                        strcpy(work, abuf+4);
                    239:                                        goto hardway;
                    240:                                }
                    241:                                for (cp = abuf; *cp == *dp && *cp; cp++, dp++)
                    242:                                        ;
                    243:                                if (*dp)
                    244:                                        goto tohard;
                    245:                                strcpy(work, cp-3);
                    246:                        }
                    247:                        fclose(it);
                    248:                        strcpy(work2, "cat");
                    249:                        strcpy(work2+3, work+3);
                    250:                        work2[4] = 0;
                    251:                        if (stat(work2, &stbuf2) < 0)
                    252:                                goto hardway;
                    253:                        strcpy(work2+3, work+3);
                    254:                        if (stat(work2, &stbuf2) < 0 || stbuf2.st_mtime < stbuf.st_mtime) {
                    255:                                printf("Reformatting page.  Wait...");
                    256:                                fflush(stdout);
                    257:                                unlink(work2);
                    258:                                sprintf(cmdbuf,
                    259:                        "%s %s > /tmp/man%d; trap '' 1 15; mv /tmp/man%d %s",
                    260:                                    NROFFCAT, work, getpid(), getpid(), work2);
                    261:                                if (system(cmdbuf)) {
                    262:                                        printf(" aborted (sorry)\n");
                    263:                                        remove();
                    264:                                        /*NOTREACHED*/
                    265:                                }
                    266:                                printf(" done\n");
                    267:                        }
                    268:                        strcpy(work, work2);
                    269:                }
                    270: hardway:
                    271:                nroff(work);
                    272:        }
                    273: }
                    274: 
                    275: nroff(cp)
                    276:        char *cp;
                    277: {
                    278:        char cmd[BUFSIZ];
                    279: 
                    280:        if (cp[0] == 'c')
                    281:                sprintf(cmd, "%s %s", nomore? CAT : MORE, cp);
                    282:        else
                    283:                sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE);
                    284:        system(cmd);
                    285: }
                    286: 
                    287: troff(cp)
                    288:        char *cp;
                    289: {
                    290:        char cmdbuf[BUFSIZ];
                    291: 
                    292:        sprintf(cmdbuf, TROFFCMD, cp);
                    293:        system(cmdbuf);
                    294: }
                    295: 
                    296: any(c, sp)
                    297:        register int c;
                    298:        register char *sp;
                    299: {
                    300:        register int d;
                    301: 
                    302:        while (d = *sp++)
                    303:                if (c == d)
                    304:                        return (1);
                    305:        return (0);
                    306: }
                    307: 
                    308: remove()
                    309: {
                    310:        char name[15];
                    311: 
                    312:        sprintf(name, "/tmp/man%d", getpid());
                    313:        unlink(name);
                    314:        exit(1);
                    315: }
                    316: 
                    317: apropos(argc, argv)
                    318:        int argc;
                    319:        char **argv;
                    320: {
                    321:        char buf[BUFSIZ];
                    322:        char *gotit;
                    323:        register char **vp;
                    324: 
                    325:        if (argc == 0) {
                    326:                fprintf(stderr, "apropos what?\n");
                    327:                exit(1);
                    328:        }
                    329:        if (freopen("/usr/lib/whatis", "r", stdin) == NULL) {
                    330:                perror("/usr/lib/whatis");
                    331:                exit (1);
                    332:        }
                    333:        gotit = (char *) calloc(1, blklen(argv));
                    334:        while (fgets(buf, sizeof buf, stdin) != NULL)
                    335:                for (vp = argv; *vp; vp++)
                    336:                        if (match(buf, *vp)) {
                    337:                                printf("%s", buf);
                    338:                                gotit[vp - argv] = 1;
                    339:                                for (vp++; *vp; vp++)
                    340:                                        if (match(buf, *vp))
                    341:                                                gotit[vp - argv] = 1;
                    342:                                break;
                    343:                        }
                    344:        for (vp = argv; *vp; vp++)
                    345:                if (gotit[vp - argv] == 0)
                    346:                        printf("%s: nothing apropriate\n", *vp);
                    347: }
                    348: 
                    349: match(buf, str)
                    350:        char *buf, *str;
                    351: {
                    352:        register char *bp, *cp;
                    353: 
                    354:        bp = buf;
                    355:        for (;;) {
                    356:                if (*bp == 0)
                    357:                        return (0);
                    358:                if (amatch(bp, str))
                    359:                        return (1);
                    360:                bp++;
                    361:        }
                    362: }
                    363: 
                    364: amatch(cp, dp)
                    365:        register char *cp, *dp;
                    366: {
                    367: 
                    368:        while (*cp && *dp && lmatch(*cp, *dp))
                    369:                cp++, dp++;
                    370:        if (*dp == 0)
                    371:                return (1);
                    372:        return (0);
                    373: }
                    374: 
                    375: lmatch(c, d)
                    376:        char c, d;
                    377: {
                    378: 
                    379:        if (c == d)
                    380:                return (1);
                    381:        if (!isalpha(c) || !isalpha(d))
                    382:                return (0);
                    383:        if (islower(c))
                    384:                c = toupper(c);
                    385:        if (islower(d))
                    386:                d = toupper(d);
                    387:        return (c == d);
                    388: }
                    389: 
                    390: blklen(ip)
                    391:        register int *ip;
                    392: {
                    393:        register int i = 0;
                    394: 
                    395:        while (*ip++)
                    396:                i++;
                    397:        return (i);
                    398: }
                    399: 
                    400: whatis(argc, argv)
                    401:        int argc;
                    402:        char **argv;
                    403: {
                    404:        register char **avp;
                    405: 
                    406:        if (argc == 0) {
                    407:                fprintf(stderr, "whatis what?\n");
                    408:                exit(1);
                    409:        }
                    410:        if (freopen("/usr/lib/whatis", "r", stdin) == NULL) {
                    411:                perror("/usr/lib/whatis");
                    412:                exit (1);
                    413:        }
                    414:        for (avp = argv; *avp; avp++)
                    415:                *avp = trim(*avp);
                    416:        whatisit(argv);
                    417:        exit(0);
                    418: }
                    419: 
                    420: whatisit(argv)
                    421:        char **argv;
                    422: {
                    423:        char buf[BUFSIZ];
                    424:        register char *gotit;
                    425:        register char **vp;
                    426: 
                    427:        gotit = (char *)calloc(1, blklen(argv));
                    428:        while (fgets(buf, sizeof buf, stdin) != NULL)
                    429:                for (vp = argv; *vp; vp++)
                    430:                        if (wmatch(buf, *vp)) {
                    431:                                printf("%s", buf);
                    432:                                gotit[vp - argv] = 1;
                    433:                                for (vp++; *vp; vp++)
                    434:                                        if (wmatch(buf, *vp))
                    435:                                                gotit[vp - argv] = 1;
                    436:                                break;
                    437:                        }
                    438:        for (vp = argv; *vp; vp++)
                    439:                if (gotit[vp - argv] == 0)
                    440:                        printf("%s: not found\n", *vp);
                    441: }
                    442: 
                    443: wmatch(buf, str)
                    444:        char *buf, *str;
                    445: {
                    446:        register char *bp, *cp;
                    447: 
                    448:        bp = buf;
                    449: again:
                    450:        cp = str;
                    451:        while (*bp && *cp && lmatch(*bp, *cp))
                    452:                bp++, cp++;
                    453:        if (*cp == 0 && (*bp == '(' || *bp == ',' || *bp == '\t' || *bp == ' '))
                    454:                return (1);
                    455:        while (isalpha(*bp) || isdigit(*bp))
                    456:                bp++;
                    457:        if (*bp != ',')
                    458:                return (0);
                    459:        bp++;
                    460:        while (isspace(*bp))
                    461:                bp++;
                    462:        goto again;
                    463: }
                    464: 
                    465: char *
                    466: trim(cp)
                    467:        register char *cp;
                    468: {
                    469:        register char *dp;
                    470: 
                    471:        for (dp = cp; *dp; dp++)
                    472:                if (*dp == '/')
                    473:                        cp = dp + 1;
                    474:        if (cp[0] != '.') {
                    475:                if (cp + 3 <= dp && dp[-2] == '.' && any(dp[-1], "cosa12345678npP"))
                    476:                        dp[-2] = 0;
                    477:                if (cp + 4 <= dp && dp[-3] == '.' && any(dp[-2], "13") && isalpha(dp[-1]))
                    478:                        dp[-3] = 0;
                    479:        }
                    480:        return (cp);
                    481: }
                    482: 
                    483: system(s)
                    484: char *s;
                    485: {
                    486:        int status, pid, w;
                    487: 
                    488:        if ((pid = vfork()) == 0) {
                    489:                execl("/bin/sh", "sh", "-c", s, 0);
                    490:                _exit(127);
                    491:        }
                    492:        while ((w = wait(&status)) != pid && w != -1)
                    493:                ;
                    494:        if (w == -1)
                    495:                status = -1;
                    496:        return (status);
                    497: }

unix.superglobalmegacorp.com

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