1*35535Sbostic /* 2*35535Sbostic * Copyright (c) 1987 Regents of the University of California. 3*35535Sbostic * All rights reserved. 4*35535Sbostic * 5*35535Sbostic * Redistribution and use in source and binary forms are permitted 6*35535Sbostic * provided that the above copyright notice and this paragraph are 7*35535Sbostic * duplicated in all such forms and that any documentation, 8*35535Sbostic * advertising materials, and other materials related to such 9*35535Sbostic * distribution and use acknowledge that the software was developed 10*35535Sbostic * by the University of California, Berkeley. The name of the 11*35535Sbostic * University may not be used to endorse or promote products derived 12*35535Sbostic * from this software without specific prior written permission. 13*35535Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*35535Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*35535Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16*35535Sbostic */ 17*35535Sbostic 18*35535Sbostic #ifndef lint 19*35535Sbostic char copyright[] = 20*35535Sbostic "@(#) Copyright (c) 1987 Regents of the University of California.\n\ 21*35535Sbostic All rights reserved.\n"; 22*35535Sbostic #endif /* not lint */ 23*35535Sbostic 24*35535Sbostic #ifndef lint 25*35535Sbostic static char sccsid[] = "@(#)whatis.c 5.1 (Berkeley) 09/18/88"; 26*35535Sbostic #endif /* not lint */ 27*35535Sbostic 28*35535Sbostic #include <sys/param.h> 29*35535Sbostic #include <stdio.h> 30*35535Sbostic #include <ctype.h> 31*35535Sbostic #include <strings.h> 32*35535Sbostic 33*35535Sbostic #define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" 34*35535Sbostic #define MAXLINELEN 1000 /* max line handled */ 35*35535Sbostic #define WHATIS "whatis" /* database name */ 36*35535Sbostic 37*35535Sbostic main(argc, argv) 38*35535Sbostic int argc; 39*35535Sbostic char **argv; 40*35535Sbostic { 41*35535Sbostic extern char *optarg; 42*35535Sbostic extern int optind; 43*35535Sbostic register char *beg, *end, **p; 44*35535Sbostic int ch, foundman = 0, *found; 45*35535Sbostic char *manpath, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1]; 46*35535Sbostic char wbuf[MAXLINELEN + 1], *getenv(), *malloc(); 47*35535Sbostic 48*35535Sbostic while ((ch = getopt(argc, argv, "M:P:")) != EOF) 49*35535Sbostic switch((char)ch) { 50*35535Sbostic case 'M': 51*35535Sbostic case 'P': /* backward compatible */ 52*35535Sbostic manpath = optarg; 53*35535Sbostic break; 54*35535Sbostic case '?': 55*35535Sbostic default: 56*35535Sbostic usage(); 57*35535Sbostic } 58*35535Sbostic argv += optind; 59*35535Sbostic argc -= optind; 60*35535Sbostic if (argc < 1) 61*35535Sbostic usage(); 62*35535Sbostic 63*35535Sbostic if (!(manpath = getenv("MANPATH"))) 64*35535Sbostic manpath = DEF_PATH; 65*35535Sbostic 66*35535Sbostic /*NOSTRICT*/ 67*35535Sbostic if (!(found = (int *)malloc((u_int)argc))) { 68*35535Sbostic fprintf(stderr, "whatis: out of space.\n"); 69*35535Sbostic exit(1); 70*35535Sbostic } 71*35535Sbostic bzero((char *)found, argc * sizeof(int)); 72*35535Sbostic 73*35535Sbostic for (p = argv; *p; ++p) /* trim full paths */ 74*35535Sbostic if (beg = rindex(*p, '/')) 75*35535Sbostic *p = beg + 1; 76*35535Sbostic 77*35535Sbostic for (beg = manpath; beg; beg = end) { /* through path list */ 78*35535Sbostic end = index(beg, ':'); 79*35535Sbostic if (!end) 80*35535Sbostic (void)sprintf(fname, "%s/%s", beg, WHATIS); 81*35535Sbostic else { 82*35535Sbostic (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS); 83*35535Sbostic ++end; 84*35535Sbostic } 85*35535Sbostic if (!freopen(fname, "r", stdin)) 86*35535Sbostic continue; 87*35535Sbostic 88*35535Sbostic /* for each file found */ 89*35535Sbostic for (foundman = 1; fgets(buf, sizeof(buf), stdin);) { 90*35535Sbostic dashtrunc(buf, wbuf); 91*35535Sbostic for (p = argv; *p; ++p) 92*35535Sbostic if (match(wbuf, *p)) { 93*35535Sbostic printf("%s", buf); 94*35535Sbostic found[p - argv] = 1; 95*35535Sbostic 96*35535Sbostic /* only print line once */ 97*35535Sbostic while (*++p) 98*35535Sbostic if (match(wbuf, *p)) 99*35535Sbostic found[p - argv] = 1; 100*35535Sbostic break; 101*35535Sbostic } 102*35535Sbostic } 103*35535Sbostic } 104*35535Sbostic if (!foundman) { 105*35535Sbostic fprintf(stderr, "whatis: no %s file found in %s.\n", 106*35535Sbostic WHATIS, manpath); 107*35535Sbostic exit(1); 108*35535Sbostic } 109*35535Sbostic for (p = argv; *p; ++p) 110*35535Sbostic if (!found[p - argv]) 111*35535Sbostic printf("%s: not found\n", *p); 112*35535Sbostic } 113*35535Sbostic 114*35535Sbostic /* 115*35535Sbostic * match -- 116*35535Sbostic * match a full word 117*35535Sbostic */ 118*35535Sbostic match(bp, str) 119*35535Sbostic register char *bp, *str; 120*35535Sbostic { 121*35535Sbostic register int len; 122*35535Sbostic register char *start; 123*35535Sbostic 124*35535Sbostic if (!*str || !*bp) 125*35535Sbostic return(0); 126*35535Sbostic for (len = strlen(str);;) { 127*35535Sbostic for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); 128*35535Sbostic if (!*bp) 129*35535Sbostic break; 130*35535Sbostic for (start = bp++; *bp && (isdigit(*bp) || isalpha(*bp)); ++bp); 131*35535Sbostic if (bp - start == len && !strncasecmp(start, str, len)) 132*35535Sbostic return(1); 133*35535Sbostic } 134*35535Sbostic return(0); 135*35535Sbostic } 136*35535Sbostic 137*35535Sbostic /* 138*35535Sbostic * dashtrunc -- 139*35535Sbostic * truncate a string at " - " 140*35535Sbostic */ 141*35535Sbostic dashtrunc(from, to) 142*35535Sbostic register char *from, *to; 143*35535Sbostic { 144*35535Sbostic register int ch; 145*35535Sbostic 146*35535Sbostic for (; (ch = *from) && ch != '\n' && 147*35535Sbostic (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from) 148*35535Sbostic *to++ = ch; 149*35535Sbostic *to = '\0'; 150*35535Sbostic } 151*35535Sbostic 152*35535Sbostic /* 153*35535Sbostic * usage -- 154*35535Sbostic * print usage message and die 155*35535Sbostic */ 156*35535Sbostic usage() 157*35535Sbostic { 158*35535Sbostic fprintf(stderr, "usage: whatis [-M path] string ...\n"); 159*35535Sbostic exit(1); 160*35535Sbostic } 161