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