|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1987 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: char copyright[] = ! 20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)apropos.c 5.6 (Berkeley) 6/29/88"; ! 26: #endif /* not lint */ ! 27: ! 28: #include <sys/param.h> ! 29: #include <stdio.h> ! 30: #include <ctype.h> ! 31: #include <strings.h> ! 32: ! 33: #define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" ! 34: #define MAXLINELEN 1000 /* max line handled */ ! 35: #define WHATIS "whatis" /* database name */ ! 36: ! 37: #define NO 0 /* no/false */ ! 38: #define YES 1 /* yes/true */ ! 39: ! 40: static char *myname; ! 41: ! 42: main(argc, argv) ! 43: int argc; ! 44: char **argv; ! 45: { ! 46: extern char *optarg; ! 47: extern int optind; ! 48: register char *beg, *end, **C; ! 49: int ch, foundman = NO, *found, isapropos; ! 50: int a_match(), w_match(), (*match)(); ! 51: char *manpath = NULL, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1]; ! 52: char wbuf[MAXLINELEN + 1], *getenv(), *malloc(); ! 53: ! 54: myname = (beg = rindex(*argv, '/')) ? beg + 1 : *argv; ! 55: if (!strcmp(myname, "apropos")) { ! 56: isapropos = YES; ! 57: match = a_match; ! 58: } ! 59: else { ! 60: isapropos = NO; ! 61: match = w_match; ! 62: } ! 63: while ((ch = getopt(argc, argv, "M:P:")) != EOF) ! 64: switch((char)ch) { ! 65: case 'M': ! 66: case 'P': /* backward contemptible */ ! 67: manpath = optarg; ! 68: break; ! 69: case '?': ! 70: default: ! 71: usage(); ! 72: } ! 73: argv += optind; ! 74: argc -= optind; ! 75: if (argc < 1) ! 76: usage(); ! 77: ! 78: if (!(manpath = getenv("MANPATH"))) ! 79: manpath = DEF_PATH; ! 80: ! 81: /*NOSTRICT*/ ! 82: if (!(found = (int *)malloc((u_int)argc))) { ! 83: fprintf(stderr, "%s: out of space.\n", myname); ! 84: exit(1); ! 85: } ! 86: bzero((char *)found, argc * sizeof(int)); ! 87: ! 88: if (isapropos) ! 89: for (C = argv; *C; ++C) /* convert to lower-case */ ! 90: lowstr(*C, *C); ! 91: else for (C = argv; *C; ++C) /* trim full paths */ ! 92: if (beg = rindex(*C, '/')) ! 93: *C = beg + 1; ! 94: ! 95: for (beg = manpath; beg; beg = end) { /* through path list */ ! 96: end = index(beg, ':'); ! 97: if (!end) ! 98: (void)sprintf(fname, "%s/%s", beg, WHATIS); ! 99: else { ! 100: (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS); ! 101: ++end; ! 102: } ! 103: if (!freopen(fname, "r", stdin)) ! 104: continue; ! 105: ! 106: /* for each file found */ ! 107: for (foundman = YES; gets(buf);) { ! 108: if (isapropos) ! 109: lowstr(buf, wbuf); ! 110: else ! 111: dashtrunc(buf, wbuf); ! 112: for (C = argv; *C; ++C) ! 113: if ((*match)(wbuf, *C)) { ! 114: puts(buf); ! 115: found[C - argv] = YES; ! 116: ! 117: /* only print line once */ ! 118: while (*++C) ! 119: if ((*match)(wbuf, *C)) ! 120: found[C - argv] = YES; ! 121: break; ! 122: } ! 123: } ! 124: } ! 125: if (!foundman) { ! 126: fprintf(stderr, "%s: no %s file found in %s.\n", myname, WHATIS, manpath); ! 127: exit(1); ! 128: } ! 129: for (C = argv; *C; ++C) ! 130: if (!found[C - argv]) ! 131: printf("%s: %s\n", *C, isapropos ? "nothing appropriate" : "not found"); ! 132: } ! 133: ! 134: /* ! 135: * a_match -- ! 136: * match for apropos; anywhere the string appears ! 137: */ ! 138: static ! 139: a_match(bp, str) ! 140: register char *bp, *str; ! 141: { ! 142: register int len; ! 143: register char test; ! 144: ! 145: if (!*bp) ! 146: return(NO); ! 147: /* backward compatible: everything matches empty string */ ! 148: if (!*str) ! 149: return(YES); ! 150: for (test = *str++, len = strlen(str); *bp;) ! 151: if (test == *bp++ && !strncmp(bp, str, len)) ! 152: return(YES); ! 153: return(NO); ! 154: } ! 155: ! 156: /* ! 157: * w_match -- ! 158: * match for whatis; looks for full word match ! 159: */ ! 160: static ! 161: w_match(bp, str) ! 162: register char *bp, *str; ! 163: { ! 164: register int len; ! 165: register char *start; ! 166: ! 167: if (!*str || !*bp) ! 168: return(NO); ! 169: for (len = strlen(str);;) { ! 170: for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); ! 171: if (!*bp) ! 172: break; ! 173: for (start = bp++; *bp && (isdigit(*bp) || isalpha(*bp)); ++bp); ! 174: if (bp - start == len && !strncasecmp(start, str, len)) ! 175: return(YES); ! 176: } ! 177: return(NO); ! 178: } ! 179: ! 180: /* ! 181: * dashtrunc -- ! 182: * truncate a string at " - " ! 183: */ ! 184: static ! 185: dashtrunc(from, to) ! 186: register char *from, *to; ! 187: { ! 188: do { ! 189: if (from[0] == ' ' && from[1] == '-' && from[2] == ' ') ! 190: break; ! 191: } while (*to++ = *from++); ! 192: *to = '\0'; ! 193: } ! 194: ! 195: /* ! 196: * lowstr -- ! 197: * convert a string to lower case ! 198: */ ! 199: static ! 200: lowstr(from, to) ! 201: register char *from, *to; ! 202: { ! 203: do { ! 204: *to++ = isupper(*from) ? tolower(*from) : *from; ! 205: } while (*from++); ! 206: } ! 207: ! 208: /* ! 209: * usage -- ! 210: * print usage message and die ! 211: */ ! 212: static ! 213: usage() ! 214: { ! 215: fprintf(stderr, "usage: %s [-M path] string ...\n", myname); ! 216: exit(1); ! 217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.