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