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