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 */
main(argc,argv)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
getlist(argcp,argvp,flagp,cntp)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
zerof()209 zerof()
210 {
211
212 if (sflag && bflag && mflag)
213 sflag = bflag = mflag = 0;
214 }
215 int count;
216 int print;
217
218
lookup(cp)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
looksrc(cp)270 looksrc(cp)
271 char *cp;
272 {
273 if (Sflag == 0) {
274 find(srcdirs, cp);
275 } else
276 findv(Sflag, Scnt, cp);
277 }
278
lookbin(cp)279 lookbin(cp)
280 char *cp;
281 {
282 if (Bflag == 0)
283 find(bindirs, cp);
284 else
285 findv(Bflag, Bcnt, cp);
286 }
287
lookman(cp)288 lookman(cp)
289 char *cp;
290 {
291 if (Mflag == 0) {
292 find(mandirs, cp);
293 } else
294 findv(Mflag, Mcnt, cp);
295 }
296
findv(dirv,dirc,cp)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
find(dirs,cp)307 find(dirs, cp)
308 char **dirs;
309 char *cp;
310 {
311
312 while (*dirs)
313 findin(*dirs++, cp);
314 }
315
findin(dir,cp)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
itsit(cp,dp)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