xref: /original-bsd/old/whereis/whereis.c (revision 04218a6a)
1 /*
2  * Copyright (c) 1980, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)whereis.c	5.3 (Berkeley) 03/10/90";
26 #endif /* not lint */
27 
28 #include <sys/param.h>
29 #include <sys/dir.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 
33 static char *bindirs[] = {
34 	"/etc",
35 	"/bin",
36 	"/usr/bin",
37 	"/usr/games",
38 	"/lib",
39 	"/usr/ucb",
40 	"/usr/lib",
41 	"/usr/local",
42 	"/usr/new",
43 	"/usr/old",
44 	"/usr/hosts",
45 	"/usr/include",
46 	0
47 };
48 static char *mandirs[] = {
49 	"/usr/man/man1",
50 	"/usr/man/man2",
51 	"/usr/man/man3",
52 	"/usr/man/man4",
53 	"/usr/man/man5",
54 	"/usr/man/man6",
55 	"/usr/man/man7",
56 	"/usr/man/man8",
57 	"/usr/man/manl",
58 	"/usr/man/mann",
59 	"/usr/man/mano",
60 	0
61 };
62 static char *srcdirs[]  = {
63 	"/usr/src/bin",
64 	"/usr/src/usr.bin",
65 	"/usr/src/etc",
66 	"/usr/src/ucb",
67 	"/usr/src/games",
68 	"/usr/src/usr.lib",
69 	"/usr/src/lib",
70 	"/usr/src/local",
71 	"/usr/src/new",
72 	"/usr/src/old",
73 	"/usr/src/include",
74 	"/usr/src/lib/libc/gen",
75 	"/usr/src/lib/libc/stdio",
76 	"/usr/src/lib/libc/sys",
77 	"/usr/src/lib/libc/net/common",
78 	"/usr/src/lib/libc/net/inet",
79 	"/usr/src/lib/libc/net/misc",
80 	"/usr/src/ucb/pascal",
81 	"/usr/src/ucb/pascal/utilities",
82 	"/usr/src/undoc",
83 	0
84 };
85 
86 char	sflag = 1;
87 char	bflag = 1;
88 char	mflag = 1;
89 char	**Sflag;
90 int	Scnt;
91 char	**Bflag;
92 int	Bcnt;
93 char	**Mflag;
94 int	Mcnt;
95 char	uflag;
96 /*
97  * whereis name
98  * look for source, documentation and binaries
99  */
100 main(argc, argv)
101 	int argc;
102 	char *argv[];
103 {
104 
105 	argc--, argv++;
106 	if (argc == 0) {
107 usage:
108 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
109 		exit(1);
110 	}
111 	do
112 		if (argv[0][0] == '-') {
113 			register char *cp = argv[0] + 1;
114 			while (*cp) switch (*cp++) {
115 
116 			case 'f':
117 				break;
118 
119 			case 'S':
120 				getlist(&argc, &argv, &Sflag, &Scnt);
121 				break;
122 
123 			case 'B':
124 				getlist(&argc, &argv, &Bflag, &Bcnt);
125 				break;
126 
127 			case 'M':
128 				getlist(&argc, &argv, &Mflag, &Mcnt);
129 				break;
130 
131 			case 's':
132 				zerof();
133 				sflag++;
134 				continue;
135 
136 			case 'u':
137 				uflag++;
138 				continue;
139 
140 			case 'b':
141 				zerof();
142 				bflag++;
143 				continue;
144 
145 			case 'm':
146 				zerof();
147 				mflag++;
148 				continue;
149 
150 			default:
151 				goto usage;
152 			}
153 			argv++;
154 		} else
155 			lookup(*argv++);
156 	while (--argc > 0);
157 	exit(0);
158 }
159 
160 getlist(argcp, argvp, flagp, cntp)
161 	char ***argvp;
162 	int *argcp;
163 	char ***flagp;
164 	int *cntp;
165 {
166 
167 	(*argvp)++;
168 	*flagp = *argvp;
169 	*cntp = 0;
170 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
171 		(*cntp)++, (*argvp)++;
172 	(*argcp)++;
173 	(*argvp)--;
174 }
175 
176 
177 zerof()
178 {
179 
180 	if (sflag && bflag && mflag)
181 		sflag = bflag = mflag = 0;
182 }
183 int	count;
184 int	print;
185 
186 
187 lookup(cp)
188 	register char *cp;
189 {
190 	register char *dp;
191 
192 	for (dp = cp; *dp; dp++)
193 		continue;
194 	for (; dp > cp; dp--) {
195 		if (*dp == '.') {
196 			*dp = 0;
197 			break;
198 		}
199 	}
200 	for (dp = cp; *dp; dp++)
201 		if (*dp == '/')
202 			cp = dp + 1;
203 	if (uflag) {
204 		print = 0;
205 		count = 0;
206 	} else
207 		print = 1;
208 again:
209 	if (print)
210 		printf("%s:", cp);
211 	if (sflag) {
212 		looksrc(cp);
213 		if (uflag && print == 0 && count != 1) {
214 			print = 1;
215 			goto again;
216 		}
217 	}
218 	count = 0;
219 	if (bflag) {
220 		lookbin(cp);
221 		if (uflag && print == 0 && count != 1) {
222 			print = 1;
223 			goto again;
224 		}
225 	}
226 	count = 0;
227 	if (mflag) {
228 		lookman(cp);
229 		if (uflag && print == 0 && count != 1) {
230 			print = 1;
231 			goto again;
232 		}
233 	}
234 	if (print)
235 		printf("\n");
236 }
237 
238 looksrc(cp)
239 	char *cp;
240 {
241 	if (Sflag == 0) {
242 		find(srcdirs, cp);
243 	} else
244 		findv(Sflag, Scnt, cp);
245 }
246 
247 lookbin(cp)
248 	char *cp;
249 {
250 	if (Bflag == 0)
251 		find(bindirs, cp);
252 	else
253 		findv(Bflag, Bcnt, cp);
254 }
255 
256 lookman(cp)
257 	char *cp;
258 {
259 	if (Mflag == 0) {
260 		find(mandirs, cp);
261 	} else
262 		findv(Mflag, Mcnt, cp);
263 }
264 
265 findv(dirv, dirc, cp)
266 	char **dirv;
267 	int dirc;
268 	char *cp;
269 {
270 
271 	while (dirc > 0)
272 		findin(*dirv++, cp), dirc--;
273 }
274 
275 find(dirs, cp)
276 	char **dirs;
277 	char *cp;
278 {
279 
280 	while (*dirs)
281 		findin(*dirs++, cp);
282 }
283 
284 findin(dir, cp)
285 	char *dir, *cp;
286 {
287 	DIR *dirp;
288 	struct direct *dp;
289 
290 	dirp = opendir(dir);
291 	if (dirp == NULL)
292 		return;
293 	while ((dp = readdir(dirp)) != NULL) {
294 		if (itsit(cp, dp->d_name)) {
295 			count++;
296 			if (print)
297 				printf(" %s/%s", dir, dp->d_name);
298 		}
299 	}
300 	closedir(dirp);
301 }
302 
303 itsit(cp, dp)
304 	register char *cp, *dp;
305 {
306 	register int i = strlen(dp);
307 
308 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
309 		return (1);
310 	while (*cp && *dp && *cp == *dp)
311 		cp++, dp++, i--;
312 	if (*cp == 0 && *dp == 0)
313 		return (1);
314 	while (isdigit(*dp))
315 		dp++;
316 	if (*cp == 0 && *dp++ == '.') {
317 		--i;
318 		while (i > 0 && *dp)
319 			if (--i, *dp++ == '.')
320 				return (*dp++ == 'C' && *dp++ == 0);
321 		return (1);
322 	}
323 	return (0);
324 }
325