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