131702Sbostic /* 231702Sbostic * Copyright (c) 1987 Regents of the University of California. 333054Sbostic * All rights reserved. 433054Sbostic * 533054Sbostic * Redistribution and use in source and binary forms are permitted 634886Sbostic * provided that the above copyright notice and this paragraph are 734886Sbostic * duplicated in all such forms and that any documentation, 834886Sbostic * advertising materials, and other materials related to such 934886Sbostic * distribution and use acknowledge that the software was developed 1034886Sbostic * by the University of California, Berkeley. The name of the 1134886Sbostic * University may not be used to endorse or promote products derived 1234886Sbostic * from this software without specific prior written permission. 1334886Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434886Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534886Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1631702Sbostic */ 1731702Sbostic 1831702Sbostic #ifndef lint 1931702Sbostic char copyright[] = 2031702Sbostic "@(#) Copyright (c) 1987 Regents of the University of California.\n\ 2131702Sbostic All rights reserved.\n"; 2233054Sbostic #endif /* not lint */ 2331702Sbostic 2431702Sbostic #ifndef lint 25*35534Sbostic static char sccsid[] = "@(#)apropos.c 5.7 (Berkeley) 09/18/88"; 2633054Sbostic #endif /* not lint */ 2731702Sbostic 2831702Sbostic #include <sys/param.h> 2931702Sbostic #include <stdio.h> 3031702Sbostic #include <ctype.h> 3133808Sbostic #include <strings.h> 3231702Sbostic 3331974Sbostic #define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" 3431712Sbostic #define MAXLINELEN 1000 /* max line handled */ 3531702Sbostic #define WHATIS "whatis" /* database name */ 3631702Sbostic 3731702Sbostic main(argc, argv) 3833808Sbostic int argc; 3933808Sbostic char **argv; 4031702Sbostic { 4133808Sbostic extern char *optarg; 4233808Sbostic extern int optind; 43*35534Sbostic register char *beg, *end, **p; 44*35534Sbostic int ch, foundman = 0, *found; 45*35534Sbostic char *manpath, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1]; 4633808Sbostic char wbuf[MAXLINELEN + 1], *getenv(), *malloc(); 4731702Sbostic 4831702Sbostic while ((ch = getopt(argc, argv, "M:P:")) != EOF) 4931702Sbostic switch((char)ch) { 50*35534Sbostic case 'M': 51*35534Sbostic case 'P': /* backward compatible */ 52*35534Sbostic manpath = optarg; 53*35534Sbostic break; 54*35534Sbostic case '?': 55*35534Sbostic default: 56*35534Sbostic usage(); 5731702Sbostic } 5831702Sbostic argv += optind; 5931702Sbostic argc -= optind; 6031702Sbostic if (argc < 1) 6131702Sbostic usage(); 6231702Sbostic 6331702Sbostic if (!(manpath = getenv("MANPATH"))) 6431702Sbostic manpath = DEF_PATH; 6531702Sbostic 6631702Sbostic /*NOSTRICT*/ 6731702Sbostic if (!(found = (int *)malloc((u_int)argc))) { 68*35534Sbostic fprintf(stderr, "apropos: out of space.\n"); 6931702Sbostic exit(1); 7031702Sbostic } 7133808Sbostic bzero((char *)found, argc * sizeof(int)); 7231702Sbostic 73*35534Sbostic for (p = argv; *p; ++p) /* convert to lower-case */ 74*35534Sbostic lowstr(*p, *p); 7531702Sbostic for (beg = manpath; beg; beg = end) { /* through path list */ 7631702Sbostic end = index(beg, ':'); 7731702Sbostic if (!end) 7831702Sbostic (void)sprintf(fname, "%s/%s", beg, WHATIS); 7931702Sbostic else { 8031702Sbostic (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS); 8131702Sbostic ++end; 8231702Sbostic } 8333808Sbostic if (!freopen(fname, "r", stdin)) 8433808Sbostic continue; 8533808Sbostic 86*35534Sbostic /* for each file found */ 87*35534Sbostic for (foundman = 1; fgets(buf, sizeof(buf), stdin);) { 88*35534Sbostic lowstr(buf, wbuf); 89*35534Sbostic for (p = argv; *p; ++p) 90*35534Sbostic if (match(wbuf, *p)) { 91*35534Sbostic printf("%s", buf); 92*35534Sbostic found[p - argv] = 1; 9331702Sbostic 9433808Sbostic /* only print line once */ 95*35534Sbostic while (*++p) 96*35534Sbostic if (match(wbuf, *p)) 97*35534Sbostic found[p - argv] = 1; 9833808Sbostic break; 9933808Sbostic } 10031702Sbostic } 10131702Sbostic } 10231702Sbostic if (!foundman) { 103*35534Sbostic fprintf(stderr, "apropos: no %s file found in %s.\n", 104*35534Sbostic WHATIS, manpath); 10531702Sbostic exit(1); 10631702Sbostic } 107*35534Sbostic for (p = argv; *p; ++p) 108*35534Sbostic if (!found[p - argv]) 109*35534Sbostic printf("%s: nothing appropriate\n", *p); 11031702Sbostic } 11131702Sbostic 11233808Sbostic /* 113*35534Sbostic * match -- 114*35534Sbostic * match anywhere the string appears 11533808Sbostic */ 116*35534Sbostic match(bp, str) 11733808Sbostic register char *bp, *str; 11831702Sbostic { 11933808Sbostic register int len; 12033808Sbostic register char test; 12131702Sbostic 12231702Sbostic if (!*bp) 123*35534Sbostic return(0); 12433808Sbostic /* backward compatible: everything matches empty string */ 12531702Sbostic if (!*str) 126*35534Sbostic return(1); 12733808Sbostic for (test = *str++, len = strlen(str); *bp;) 12833808Sbostic if (test == *bp++ && !strncmp(bp, str, len)) 129*35534Sbostic return(1); 130*35534Sbostic return(0); 13131702Sbostic } 13231702Sbostic 13333808Sbostic /* 13433808Sbostic * lowstr -- 13533808Sbostic * convert a string to lower case 13633808Sbostic */ 13733808Sbostic lowstr(from, to) 13833808Sbostic register char *from, *to; 13933808Sbostic { 140*35534Sbostic register char ch; 141*35534Sbostic 142*35534Sbostic while ((ch = *from++) && ch != '\n') 143*35534Sbostic *to++ = isupper(ch) ? tolower(ch) : ch; 144*35534Sbostic *to = '\0'; 14533808Sbostic } 14633808Sbostic 14733808Sbostic /* 14833808Sbostic * usage -- 14933808Sbostic * print usage message and die 15033808Sbostic */ 15131702Sbostic usage() 15231702Sbostic { 153*35534Sbostic fprintf(stderr, "usage: apropos [-M path] string ...\n"); 15431702Sbostic exit(1); 15531702Sbostic } 156