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