xref: /original-bsd/usr.bin/whatis/whatis.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1987, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1987, 1993\n\
11 	The Regents of the University of California.  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)whatis.c	8.1 (Berkeley) 06/06/93";
16 #endif /* not lint */
17 
18 #include <sys/param.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include "../man/pathnames.h"
24 
25 #define	MAXLINELEN	256			/* max line handled */
26 
27 char *progname;
28 
29 static int *found, foundman;
30 
31 main(argc, argv)
32 	int argc;
33 	char **argv;
34 {
35 	extern char *optarg;
36 	extern int optind;
37 	register char *beg, **p;
38 	int ch;
39 	char *p_augment, *p_path, **getdb();
40 
41 	progname = "whatis";
42 	p_augment = p_path = NULL;
43 	while ((ch = getopt(argc, argv, "M:m:P:")) != EOF)
44 		switch((char)ch) {
45 		case 'M':
46 		case 'P':		/* backward compatible */
47 			p_path = optarg;
48 			break;
49 		case 'm':
50 			p_augment = optarg;
51 			break;
52 		case '?':
53 		default:
54 			usage();
55 		}
56 	argv += optind;
57 	argc -= optind;
58 
59 	if (argc < 1)
60 		usage();
61 
62 	/*NOSTRICT*/
63 	if (!(found = (int *)malloc((u_int)argc)))
64 		enomem();
65 	bzero((char *)found, argc * sizeof(int));
66 
67 	for (p = argv; *p; ++p)			/* trim full paths */
68 		if (beg = rindex(*p, '/'))
69 			*p = beg + 1;
70 
71 	if (p_augment)
72 		whatis(argv, p_augment, 1);
73 	if (p_path || (p_path = getenv("MANPATH")))
74 		whatis(argv, p_path, 1);
75 	else
76 		for (p = getdb(); *p; ++p)
77 			whatis(argv, *p, 0);
78 
79 	if (!foundman) {
80 		fprintf(stderr, "whatis: no %s file found.\n", _PATH_WHATIS);
81 		exit(1);
82 	}
83 	for (p = argv; *p; ++p)
84 		if (!found[p - argv])
85 			printf("%s: not found\n", *p);
86 }
87 
88 whatis(argv, path, buildpath)
89 	char **argv, *path;
90 	int buildpath;
91 {
92 	register char *end, *name, **p;
93 	char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1];
94 
95 	for (name = path; name; name = end) {	/* through name list */
96 		if (end = index(name, ':'))
97 			*end++ = '\0';
98 
99 		if (buildpath) {
100 			char hold[MAXPATHLEN + 1];
101 
102 			(void)sprintf(hold, "%s/%s", name, _PATH_WHATIS);
103 			name = hold;
104 		}
105 
106 		if (!freopen(name, "r", stdin))
107 			continue;
108 
109 		foundman = 1;
110 
111 		/* for each file found */
112 		while (fgets(buf, sizeof(buf), stdin)) {
113 			dashtrunc(buf, wbuf);
114 			for (p = argv; *p; ++p)
115 				if (match(wbuf, *p)) {
116 					printf("%s", buf);
117 					found[p - argv] = 1;
118 
119 					/* only print line once */
120 					while (*++p)
121 						if (match(wbuf, *p))
122 							found[p - argv] = 1;
123 					break;
124 				}
125 		}
126 	}
127 }
128 
129 /*
130  * match --
131  *	match a full word
132  */
133 match(bp, str)
134 	register char *bp, *str;
135 {
136 	register int len;
137 	register char *start;
138 
139 	if (!*str || !*bp)
140 		return(0);
141 	for (len = strlen(str);;) {
142 		for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp);
143 		if (!*bp)
144 			break;
145 		for (start = bp++;
146 		    *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp);
147 		if (bp - start == len && !strncasecmp(start, str, len))
148 			return(1);
149 	}
150 	return(0);
151 }
152 
153 /*
154  * dashtrunc --
155  *	truncate a string at " - "
156  */
157 dashtrunc(from, to)
158 	register char *from, *to;
159 {
160 	register int ch;
161 
162 	for (; (ch = *from) && ch != '\n' &&
163 	    (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from)
164 		*to++ = ch;
165 	*to = '\0';
166 }
167 
168 /*
169  * usage --
170  *	print usage message and die
171  */
172 usage()
173 {
174 	(void)fprintf(stderr,
175 	    "usage: whatis [-M path] [-m path] command ...\n");
176 	exit(1);
177 }
178