xref: /original-bsd/old/whereis/whereis.c (revision 5e5b7b99)
1 /*-
2  * Copyright (c) 1980 The 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) 1980 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)whereis.c	5.5 (Berkeley) 04/18/91";
16 #endif /* not lint */
17 
18 #include <sys/param.h>
19 #include <sys/dir.h>
20 #include <stdio.h>
21 #include <ctype.h>
22 
23 static char *bindirs[] = {
24 	"/bin",
25 	"/sbin",
26 	"/usr/ucb",
27 	"/usr/bin",
28 	"/usr/sbin",
29 	"/usr/old",
30 	"/usr/contrib",
31 	"/usr/games",
32 	"/usr/local",
33 	"/usr/libexec",
34 	"/usr/include",
35 	"/usr/hosts",
36 	"/usr/share", /*?*/
37 	"/etc",
38 #ifdef notdef
39 	/* before reorg */
40 	"/etc",
41 	"/bin",
42 	"/usr/bin",
43 	"/usr/games",
44 	"/lib",
45 	"/usr/ucb",
46 	"/usr/lib",
47 	"/usr/local",
48 	"/usr/new",
49 	"/usr/old",
50 	"/usr/hosts",
51 	"/usr/include",
52 #endif
53 	0
54 };
55 /* This needs to be redone - man pages live with sources */
56 static char *mandirs[] = {
57 	"/usr/man/man1",
58 	"/usr/man/man2",
59 	"/usr/man/man3",
60 	"/usr/man/man4",
61 	"/usr/man/man5",
62 	"/usr/man/man6",
63 	"/usr/man/man7",
64 	"/usr/man/man8",
65 	"/usr/man/manl",
66 	"/usr/man/mann",
67 	"/usr/man/mano",
68 	0
69 };
70 static char *srcdirs[]  = {
71 	"/usr/src/bin",
72 	"/usr/src/sbin",
73 	"/usr/src/etc",
74 	"/usr/src/pgrm",
75 	"/usr/src/usr.bin",
76 	"/usr/src/usr.sbin",
77 	"/usr/src/usr.ucb",
78 	"/usr/src/usr.new",
79 	"/usr/src/usr.lib",
80 	"/usr/src/libexec",
81 	"/usr/src/libdata",
82 	"/usr/src/share",
83 	"/usr/src/contrib",
84 	"/usr/src/athena",
85 	"/usr/src/devel",
86 	"/usr/src/games",
87 	"/usr/src/local",
88 	"/usr/src/man",
89 	"/usr/src/root",
90 	"/usr/src/old",
91 	"/usr/src/include",
92 	/* still need libs */
93 #ifdef notdef /* before reorg */
94 	"/usr/src/bin",
95 	"/usr/src/usr.bin",
96 	"/usr/src/etc",
97 	"/usr/src/ucb",
98 	"/usr/src/games",
99 	"/usr/src/usr.lib",
100 	"/usr/src/lib",
101 	"/usr/src/local",
102 	"/usr/src/new",
103 	"/usr/src/old",
104 	"/usr/src/include",
105 	"/usr/src/lib/libc/gen",
106 	"/usr/src/lib/libc/stdio",
107 	"/usr/src/lib/libc/sys",
108 	"/usr/src/lib/libc/net/common",
109 	"/usr/src/lib/libc/net/inet",
110 	"/usr/src/lib/libc/net/misc",
111 	"/usr/src/ucb/pascal",
112 	"/usr/src/ucb/pascal/utilities",
113 	"/usr/src/undoc",
114 #endif
115 	0
116 };
117 
118 char	sflag = 1;
119 char	bflag = 1;
120 char	mflag = 1;
121 char	**Sflag;
122 int	Scnt;
123 char	**Bflag;
124 int	Bcnt;
125 char	**Mflag;
126 int	Mcnt;
127 char	uflag;
128 /*
129  * whereis name
130  * look for source, documentation and binaries
131  */
132 main(argc, argv)
133 	int argc;
134 	char *argv[];
135 {
136 
137 	argc--, argv++;
138 	if (argc == 0) {
139 usage:
140 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
141 		exit(1);
142 	}
143 	do
144 		if (argv[0][0] == '-') {
145 			register char *cp = argv[0] + 1;
146 			while (*cp) switch (*cp++) {
147 
148 			case 'f':
149 				break;
150 
151 			case 'S':
152 				getlist(&argc, &argv, &Sflag, &Scnt);
153 				break;
154 
155 			case 'B':
156 				getlist(&argc, &argv, &Bflag, &Bcnt);
157 				break;
158 
159 			case 'M':
160 				getlist(&argc, &argv, &Mflag, &Mcnt);
161 				break;
162 
163 			case 's':
164 				zerof();
165 				sflag++;
166 				continue;
167 
168 			case 'u':
169 				uflag++;
170 				continue;
171 
172 			case 'b':
173 				zerof();
174 				bflag++;
175 				continue;
176 
177 			case 'm':
178 				zerof();
179 				mflag++;
180 				continue;
181 
182 			default:
183 				goto usage;
184 			}
185 			argv++;
186 		} else
187 			lookup(*argv++);
188 	while (--argc > 0);
189 	exit(0);
190 }
191 
192 getlist(argcp, argvp, flagp, cntp)
193 	char ***argvp;
194 	int *argcp;
195 	char ***flagp;
196 	int *cntp;
197 {
198 
199 	(*argvp)++;
200 	*flagp = *argvp;
201 	*cntp = 0;
202 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
203 		(*cntp)++, (*argvp)++;
204 	(*argcp)++;
205 	(*argvp)--;
206 }
207 
208 
209 zerof()
210 {
211 
212 	if (sflag && bflag && mflag)
213 		sflag = bflag = mflag = 0;
214 }
215 int	count;
216 int	print;
217 
218 
219 lookup(cp)
220 	register char *cp;
221 {
222 	register char *dp;
223 
224 	for (dp = cp; *dp; dp++)
225 		continue;
226 	for (; dp > cp; dp--) {
227 		if (*dp == '.') {
228 			*dp = 0;
229 			break;
230 		}
231 	}
232 	for (dp = cp; *dp; dp++)
233 		if (*dp == '/')
234 			cp = dp + 1;
235 	if (uflag) {
236 		print = 0;
237 		count = 0;
238 	} else
239 		print = 1;
240 again:
241 	if (print)
242 		printf("%s:", cp);
243 	if (sflag) {
244 		looksrc(cp);
245 		if (uflag && print == 0 && count != 1) {
246 			print = 1;
247 			goto again;
248 		}
249 	}
250 	count = 0;
251 	if (bflag) {
252 		lookbin(cp);
253 		if (uflag && print == 0 && count != 1) {
254 			print = 1;
255 			goto again;
256 		}
257 	}
258 	count = 0;
259 	if (mflag) {
260 		lookman(cp);
261 		if (uflag && print == 0 && count != 1) {
262 			print = 1;
263 			goto again;
264 		}
265 	}
266 	if (print)
267 		printf("\n");
268 }
269 
270 looksrc(cp)
271 	char *cp;
272 {
273 	if (Sflag == 0) {
274 		find(srcdirs, cp);
275 	} else
276 		findv(Sflag, Scnt, cp);
277 }
278 
279 lookbin(cp)
280 	char *cp;
281 {
282 	if (Bflag == 0)
283 		find(bindirs, cp);
284 	else
285 		findv(Bflag, Bcnt, cp);
286 }
287 
288 lookman(cp)
289 	char *cp;
290 {
291 	if (Mflag == 0) {
292 		find(mandirs, cp);
293 	} else
294 		findv(Mflag, Mcnt, cp);
295 }
296 
297 findv(dirv, dirc, cp)
298 	char **dirv;
299 	int dirc;
300 	char *cp;
301 {
302 
303 	while (dirc > 0)
304 		findin(*dirv++, cp), dirc--;
305 }
306 
307 find(dirs, cp)
308 	char **dirs;
309 	char *cp;
310 {
311 
312 	while (*dirs)
313 		findin(*dirs++, cp);
314 }
315 
316 findin(dir, cp)
317 	char *dir, *cp;
318 {
319 	DIR *dirp;
320 	struct direct *dp;
321 
322 	dirp = opendir(dir);
323 	if (dirp == NULL)
324 		return;
325 	while ((dp = readdir(dirp)) != NULL) {
326 		if (itsit(cp, dp->d_name)) {
327 			count++;
328 			if (print)
329 				printf(" %s/%s", dir, dp->d_name);
330 		}
331 	}
332 	closedir(dirp);
333 }
334 
335 itsit(cp, dp)
336 	register char *cp, *dp;
337 {
338 	register int i = strlen(dp);
339 
340 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
341 		return (1);
342 	while (*cp && *dp && *cp == *dp)
343 		cp++, dp++, i--;
344 	if (*cp == 0 && *dp == 0)
345 		return (1);
346 	while (isdigit(*dp))
347 		dp++;
348 	if (*cp == 0 && *dp++ == '.') {
349 		--i;
350 		while (i > 0 && *dp)
351 			if (--i, *dp++ == '.')
352 				return (*dp++ == 'C' && *dp++ == 0);
353 		return (1);
354 	}
355 	return (0);
356 }
357