xref: /illumos-gate/usr/src/ucbcmd/whereis/whereis.c (revision 69b1fd3f24d0ee2e682883606201c61f52085805)
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
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
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
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
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
272 looksrc(char *cp)
273 {
274 	if (Sflag == 0) {
275 		find(srcdirs, cp);
276 	} else
277 		findv(Sflag, Scnt, cp);
278 }
279 
280 void
281 lookbin(char *cp)
282 {
283 	if (Bflag == 0)
284 		find(bindirs, cp);
285 	else
286 		findv(Bflag, Bcnt, cp);
287 }
288 
289 void
290 lookman(char *cp)
291 {
292 	if (Mflag == 0) {
293 		find(mandirs, cp);
294 	} else
295 		findv(Mflag, Mcnt, cp);
296 }
297 
298 void
299 findv(char **dirv, int dirc, char *cp)
300 {
301 
302 	while (dirc > 0)
303 		findin(*dirv++, cp), dirc--;
304 }
305 
306 void
307 find(char **dirs, char *cp)
308 {
309 
310 	while (*dirs)
311 		findin(*dirs++, cp);
312 }
313 
314 void
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
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