135535Sbostic /* 235535Sbostic * Copyright (c) 1987 Regents of the University of California. 335535Sbostic * All rights reserved. 435535Sbostic * 535535Sbostic * Redistribution and use in source and binary forms are permitted 635535Sbostic * provided that the above copyright notice and this paragraph are 735535Sbostic * duplicated in all such forms and that any documentation, 835535Sbostic * advertising materials, and other materials related to such 935535Sbostic * distribution and use acknowledge that the software was developed 1035535Sbostic * by the University of California, Berkeley. The name of the 1135535Sbostic * University may not be used to endorse or promote products derived 1235535Sbostic * from this software without specific prior written permission. 1335535Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435535Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535535Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1635535Sbostic */ 1735535Sbostic 1835535Sbostic #ifndef lint 1935535Sbostic char copyright[] = 2035535Sbostic "@(#) Copyright (c) 1987 Regents of the University of California.\n\ 2135535Sbostic All rights reserved.\n"; 2235535Sbostic #endif /* not lint */ 2335535Sbostic 2435535Sbostic #ifndef lint 25*35536Sbostic static char sccsid[] = "@(#)whatis.c 5.2 (Berkeley) 09/19/88"; 2635535Sbostic #endif /* not lint */ 2735535Sbostic 2835535Sbostic #include <sys/param.h> 2935535Sbostic #include <stdio.h> 3035535Sbostic #include <ctype.h> 3135535Sbostic #include <strings.h> 3235535Sbostic 3335535Sbostic #define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" 3435535Sbostic #define MAXLINELEN 1000 /* max line handled */ 3535535Sbostic #define WHATIS "whatis" /* database name */ 3635535Sbostic 3735535Sbostic main(argc, argv) 3835535Sbostic int argc; 3935535Sbostic char **argv; 4035535Sbostic { 4135535Sbostic extern char *optarg; 4235535Sbostic extern int optind; 4335535Sbostic register char *beg, *end, **p; 4435535Sbostic int ch, foundman = 0, *found; 4535535Sbostic char *manpath, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1]; 4635535Sbostic char wbuf[MAXLINELEN + 1], *getenv(), *malloc(); 4735535Sbostic 4835535Sbostic while ((ch = getopt(argc, argv, "M:P:")) != EOF) 4935535Sbostic switch((char)ch) { 5035535Sbostic case 'M': 5135535Sbostic case 'P': /* backward compatible */ 5235535Sbostic manpath = optarg; 5335535Sbostic break; 5435535Sbostic case '?': 5535535Sbostic default: 5635535Sbostic usage(); 5735535Sbostic } 5835535Sbostic argv += optind; 5935535Sbostic argc -= optind; 6035535Sbostic if (argc < 1) 6135535Sbostic usage(); 6235535Sbostic 6335535Sbostic if (!(manpath = getenv("MANPATH"))) 6435535Sbostic manpath = DEF_PATH; 6535535Sbostic 6635535Sbostic /*NOSTRICT*/ 6735535Sbostic if (!(found = (int *)malloc((u_int)argc))) { 6835535Sbostic fprintf(stderr, "whatis: out of space.\n"); 6935535Sbostic exit(1); 7035535Sbostic } 7135535Sbostic bzero((char *)found, argc * sizeof(int)); 7235535Sbostic 7335535Sbostic for (p = argv; *p; ++p) /* trim full paths */ 7435535Sbostic if (beg = rindex(*p, '/')) 7535535Sbostic *p = beg + 1; 7635535Sbostic 7735535Sbostic for (beg = manpath; beg; beg = end) { /* through path list */ 7835535Sbostic end = index(beg, ':'); 7935535Sbostic if (!end) 8035535Sbostic (void)sprintf(fname, "%s/%s", beg, WHATIS); 8135535Sbostic else { 8235535Sbostic (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS); 8335535Sbostic ++end; 8435535Sbostic } 8535535Sbostic if (!freopen(fname, "r", stdin)) 8635535Sbostic continue; 8735535Sbostic 8835535Sbostic /* for each file found */ 8935535Sbostic for (foundman = 1; fgets(buf, sizeof(buf), stdin);) { 9035535Sbostic dashtrunc(buf, wbuf); 9135535Sbostic for (p = argv; *p; ++p) 9235535Sbostic if (match(wbuf, *p)) { 9335535Sbostic printf("%s", buf); 9435535Sbostic found[p - argv] = 1; 9535535Sbostic 9635535Sbostic /* only print line once */ 9735535Sbostic while (*++p) 9835535Sbostic if (match(wbuf, *p)) 9935535Sbostic found[p - argv] = 1; 10035535Sbostic break; 10135535Sbostic } 10235535Sbostic } 10335535Sbostic } 10435535Sbostic if (!foundman) { 10535535Sbostic fprintf(stderr, "whatis: no %s file found in %s.\n", 10635535Sbostic WHATIS, manpath); 10735535Sbostic exit(1); 10835535Sbostic } 10935535Sbostic for (p = argv; *p; ++p) 11035535Sbostic if (!found[p - argv]) 11135535Sbostic printf("%s: not found\n", *p); 11235535Sbostic } 11335535Sbostic 11435535Sbostic /* 11535535Sbostic * match -- 11635535Sbostic * match a full word 11735535Sbostic */ 11835535Sbostic match(bp, str) 11935535Sbostic register char *bp, *str; 12035535Sbostic { 12135535Sbostic register int len; 12235535Sbostic register char *start; 12335535Sbostic 12435535Sbostic if (!*str || !*bp) 12535535Sbostic return(0); 12635535Sbostic for (len = strlen(str);;) { 12735535Sbostic for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); 12835535Sbostic if (!*bp) 12935535Sbostic break; 130*35536Sbostic for (start = bp++; 131*35536Sbostic *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp); 13235535Sbostic if (bp - start == len && !strncasecmp(start, str, len)) 13335535Sbostic return(1); 13435535Sbostic } 13535535Sbostic return(0); 13635535Sbostic } 13735535Sbostic 13835535Sbostic /* 13935535Sbostic * dashtrunc -- 14035535Sbostic * truncate a string at " - " 14135535Sbostic */ 14235535Sbostic dashtrunc(from, to) 14335535Sbostic register char *from, *to; 14435535Sbostic { 14535535Sbostic register int ch; 14635535Sbostic 14735535Sbostic for (; (ch = *from) && ch != '\n' && 14835535Sbostic (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from) 14935535Sbostic *to++ = ch; 15035535Sbostic *to = '\0'; 15135535Sbostic } 15235535Sbostic 15335535Sbostic /* 15435535Sbostic * usage -- 15535535Sbostic * print usage message and die 15635535Sbostic */ 15735535Sbostic usage() 15835535Sbostic { 15935535Sbostic fprintf(stderr, "usage: whatis [-M path] string ...\n"); 16035535Sbostic exit(1); 16135535Sbostic } 162