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