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