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: }

Defined functions

a_match defined in line 138; used 2 times
dashtrunc defined in line 184; used 1 times
lowstr defined in line 199; used 2 times
main defined in line 42; never used
usage defined in line 212; used 2 times
w_match defined in line 160; used 2 times

Defined variables

copyright defined in line 19; never used
myname defined in line 40; used 5 times
sccsid defined in line 25; never used

Defined macros

DEF_PATH defined in line 33; used 1 times
  • in line 79
MAXLINELEN defined in line 34; used 2 times
NO defined in line 37; used 6 times
WHATIS defined in line 35; used 3 times
YES defined in line 38; used 7 times
Last modified: 1988-12-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3352
Valid CSS Valid XHTML 1.0 Strict