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