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