Annotation of 41BSD/cmd/man/man.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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