|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.