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