131702Sbostic /* 262098Sbostic * Copyright (c) 1987, 1993 362098Sbostic * The Regents of the University of California. All rights reserved. 433054Sbostic * 542741Sbostic * %sccs.include.redist.c% 631702Sbostic */ 731702Sbostic 831702Sbostic #ifndef lint 962098Sbostic static char copyright[] = 1062098Sbostic "@(#) Copyright (c) 1987, 1993\n\ 1162098Sbostic The Regents of the University of California. All rights reserved.\n"; 1233054Sbostic #endif /* not lint */ 1331702Sbostic 1431702Sbostic #ifndef lint 15*65270Sbostic static char sccsid[] = "@(#)apropos.c 8.4 (Berkeley) 01/02/94"; 1633054Sbostic #endif /* not lint */ 1731702Sbostic 1831702Sbostic #include <sys/param.h> 1965268Sbostic #include <sys/queue.h> 2065268Sbostic 2165268Sbostic #include <ctype.h> 2265268Sbostic #include <err.h> 2331702Sbostic #include <stdio.h> 2465268Sbostic #include <stdlib.h> 2542051Sbostic #include <string.h> 2665268Sbostic 2765268Sbostic #include "../man/config.h" 2840389Sbostic #include "../man/pathnames.h" 2931702Sbostic 3051191Sbostic #define MAXLINELEN 1024 /* max line handled */ 3131702Sbostic 3242403Sbostic static int *found, foundman; 3342403Sbostic 3465268Sbostic int 3531702Sbostic main(argc, argv) 3633808Sbostic int argc; 3765268Sbostic char *argv[]; 3831702Sbostic { 3933808Sbostic extern char *optarg; 4033808Sbostic extern int optind; 4165268Sbostic ENTRY *ep; 42*65270Sbostic int ch, rv; 4365269Sbostic char *conffile, **p, *p_augment, *p_path; 4431702Sbostic 4565269Sbostic conffile = NULL; 4640389Sbostic p_augment = p_path = NULL; 4765269Sbostic while ((ch = getopt(argc, argv, "C:M:m:P:")) != EOF) 4865268Sbostic switch (ch) { 4965269Sbostic case 'C': 5065269Sbostic conffile = optarg; 5165269Sbostic break; 5235534Sbostic case 'M': 5335534Sbostic case 'P': /* backward compatible */ 5440389Sbostic p_path = optarg; 5535534Sbostic break; 5640389Sbostic case 'm': 5740389Sbostic p_augment = optarg; 5840389Sbostic break; 5935534Sbostic case '?': 6035534Sbostic default: 6135534Sbostic usage(); 6231702Sbostic } 6331702Sbostic argv += optind; 6431702Sbostic argc -= optind; 6540389Sbostic 6631702Sbostic if (argc < 1) 6731702Sbostic usage(); 6831702Sbostic 69*65270Sbostic if ((found = malloc((u_int)argc * sizeof(int))) == NULL) 7065268Sbostic err(1, NULL); 7165268Sbostic memset(found, 0, argc * sizeof(int)); 7231702Sbostic 7335534Sbostic for (p = argv; *p; ++p) /* convert to lower-case */ 7435534Sbostic lowstr(*p, *p); 7540389Sbostic 7640389Sbostic if (p_augment) 7742403Sbostic apropos(argv, p_augment, 1); 7842403Sbostic if (p_path || (p_path = getenv("MANPATH"))) 7942403Sbostic apropos(argv, p_path, 1); 8065268Sbostic else { 8165269Sbostic config(conffile); 8265268Sbostic ep = getlist("_whatdb"); 8365268Sbostic if (ep != NULL) 8465268Sbostic ep = ep->list.qe_next; 8565268Sbostic for (; ep != NULL; ep = ep->list.qe_next) 8665268Sbostic apropos(argv, ep->s, 0); 8765268Sbostic } 8842403Sbostic 8940389Sbostic if (!foundman) { 9042403Sbostic (void)fprintf(stderr, 9165268Sbostic "apropos: no %s file found.\n", _PATH_WHATIS); 9240389Sbostic exit(1); 9340389Sbostic } 94*65270Sbostic rv = 1; 9540389Sbostic for (p = argv; *p; ++p) 96*65270Sbostic if (found[p - argv]) 97*65270Sbostic rv = 0; 98*65270Sbostic else 9940389Sbostic (void)printf("%s: nothing appropriate\n", *p); 100*65270Sbostic exit(rv); 10140389Sbostic } 10240389Sbostic 10342403Sbostic apropos(argv, path, buildpath) 10440389Sbostic char **argv, *path; 10542403Sbostic int buildpath; 10640389Sbostic { 10742403Sbostic register char *end, *name, **p; 10840389Sbostic char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1]; 10940389Sbostic 11042403Sbostic for (name = path; name; name = end) { /* through name list */ 11142403Sbostic if (end = index(name, ':')) 11242403Sbostic *end++ = '\0'; 11342403Sbostic 11442403Sbostic if (buildpath) { 11542403Sbostic char hold[MAXPATHLEN + 1]; 11642403Sbostic 11742403Sbostic (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS); 11842403Sbostic name = hold; 11931702Sbostic } 12042403Sbostic 12142403Sbostic if (!freopen(name, "r", stdin)) 12233808Sbostic continue; 12333808Sbostic 12442403Sbostic foundman = 1; 12542403Sbostic 12635534Sbostic /* for each file found */ 12742403Sbostic while (fgets(buf, sizeof(buf), stdin)) { 12840389Sbostic if (!index(buf, '\n')) { 12940389Sbostic (void)fprintf(stderr, 13042403Sbostic "apropos: %s line too long.\n", name); 13151191Sbostic continue; 13240389Sbostic } 13335534Sbostic lowstr(buf, wbuf); 13435534Sbostic for (p = argv; *p; ++p) 13535534Sbostic if (match(wbuf, *p)) { 13640389Sbostic (void)printf("%s", buf); 13735534Sbostic found[p - argv] = 1; 13831702Sbostic 13933808Sbostic /* only print line once */ 14035534Sbostic while (*++p) 14135534Sbostic if (match(wbuf, *p)) 14235534Sbostic found[p - argv] = 1; 14333808Sbostic break; 14433808Sbostic } 14531702Sbostic } 14631702Sbostic } 14731702Sbostic } 14831702Sbostic 14933808Sbostic /* 15035534Sbostic * match -- 15135534Sbostic * match anywhere the string appears 15233808Sbostic */ 15335534Sbostic match(bp, str) 15433808Sbostic register char *bp, *str; 15531702Sbostic { 15633808Sbostic register int len; 15733808Sbostic register char test; 15831702Sbostic 15931702Sbostic if (!*bp) 16035534Sbostic return(0); 16133808Sbostic /* backward compatible: everything matches empty string */ 16231702Sbostic if (!*str) 16335534Sbostic return(1); 16433808Sbostic for (test = *str++, len = strlen(str); *bp;) 16533808Sbostic if (test == *bp++ && !strncmp(bp, str, len)) 16635534Sbostic return(1); 16735534Sbostic return(0); 16831702Sbostic } 16931702Sbostic 17033808Sbostic /* 17133808Sbostic * lowstr -- 17233808Sbostic * convert a string to lower case 17333808Sbostic */ 17433808Sbostic lowstr(from, to) 17533808Sbostic register char *from, *to; 17633808Sbostic { 17735534Sbostic register char ch; 17835534Sbostic 17935534Sbostic while ((ch = *from++) && ch != '\n') 18035534Sbostic *to++ = isupper(ch) ? tolower(ch) : ch; 18135534Sbostic *to = '\0'; 18233808Sbostic } 18333808Sbostic 18433808Sbostic /* 18533808Sbostic * usage -- 18633808Sbostic * print usage message and die 18733808Sbostic */ 18831702Sbostic usage() 18931702Sbostic { 19040389Sbostic (void)fprintf(stderr, 19165269Sbostic "usage: apropos [-C file] [-M path] [-m path] keyword ...\n"); 19231702Sbostic exit(1); 19331702Sbostic } 194