xref: /original-bsd/old/whereis/whereis.c (revision d25e1985)
1 static char *sccsid = "@(#)whereis.c	4.1 (Berkeley) 10/01/80";
2 #include <sys/types.h>
3 #include <stdio.h>
4 #include <ctype.h>
5 #include <sys/dir.h>
6 #include <whoami.h>
7 
8 static char *bindirs[] = {
9 	"/etc",
10 	"/bin",
11 	"/usr/bin",
12 	"/usr/games",
13 #ifdef CSVAX
14 	"/lib",
15 	"/usr/ucb",
16 	"/usr/lib",
17 	"/usr/local",
18 	"/usr/new",
19 	"/usr/old",
20 #endif
21 #ifdef CORY
22 	"/usr/bin/eecs",
23 	"/usr/bin/new",
24 	"/usr/bin/v7",
25 	"/usr/bin/old",
26 	"/usr/bin/UNSUPPORTED",
27 #endif
28 	0
29 };
30 static char *mandirs[] = {
31 	"/usr/man/man1",
32 	"/usr/man/man2",
33 	"/usr/man/man3",
34 	"/usr/man/man4",
35 	"/usr/man/man5",
36 	"/usr/man/man6",
37 	"/usr/man/man7",
38 	"/usr/man/man8",
39 #ifdef CORY
40 	"/usr/man/manu",
41 	"/usr/man/manc",
42 	"/usr/man/manv7",
43 	"/usr/bin/eecs/mane",
44 #endif
45 	0
46 };
47 static char *srcdirs[]  = {
48 	"/usr/src/cmd",
49 	"/usr/src/games",
50 	"/usr/src/libc/gen",
51 	"/usr/src/libc/stdio",
52 #ifdef CSVAX
53 	"/usr/src/libc/sys",
54 	"/usr/src/new",
55 	"/usr/src/old",
56 	"/usr/src/local",
57 	"/usr/src/undoc",
58 #endif
59 #ifdef CORY
60 	"/usr/bin/eecs/src",
61 	"/usr/src/cmd/v7",
62 	"/usr/src/cmd/new",
63 	"/usr/src/cmd/old",
64 	"/usr/src/cmd/UNSUPPORTED",
65 #endif
66 	0
67 };
68 
69 char	sflag = 1;
70 char	bflag = 1;
71 char	mflag = 1;
72 char	**Sflag;
73 int	Scnt;
74 char	**Bflag;
75 int	Bcnt;
76 char	**Mflag;
77 int	Mcnt;
78 char	uflag;
79 /*
80  * whereis name
81  * look for source, documentation and binaries
82  */
83 main(argc, argv)
84 	int argc;
85 	char *argv[];
86 {
87 
88 #ifdef CORY
89 	if (getuid() == 0)
90 		nice(-20);
91 	if (((getuid() >> 8) & 0377) > 10)
92 		setuid(getuid());
93 #endif
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 }
147 
148 getlist(argcp, argvp, flagp, cntp)
149 	char ***argvp;
150 	int *argcp;
151 	char ***flagp;
152 	int *cntp;
153 {
154 
155 	(*argvp)++;
156 	*flagp = *argvp;
157 	*cntp = 0;
158 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
159 		(*cntp)++, (*argvp)++;
160 	(*argcp)++;
161 	(*argvp)--;
162 }
163 
164 
165 zerof()
166 {
167 
168 	if (sflag && bflag && mflag)
169 		sflag = bflag = mflag = 0;
170 }
171 int	count;
172 int	print;
173 
174 
175 lookup(cp)
176 	register char *cp;
177 {
178 	register char *dp;
179 
180 	for (dp = cp; *dp; dp++)
181 		continue;
182 	for (; dp > cp; dp--) {
183 		if (*dp == '.') {
184 			*dp = 0;
185 			break;
186 		}
187 	}
188 	for (dp = cp; *dp; dp++)
189 		if (*dp == '/')
190 			cp = dp + 1;
191 	if (uflag) {
192 		print = 0;
193 		count = 0;
194 	} else
195 		print = 1;
196 again:
197 	if (print)
198 		printf("%s:", cp);
199 	if (sflag) {
200 		looksrc(cp);
201 		if (uflag && print == 0 && count != 1) {
202 			print = 1;
203 			goto again;
204 		}
205 	}
206 	count = 0;
207 	if (bflag) {
208 		lookbin(cp);
209 		if (uflag && print == 0 && count != 1) {
210 			print = 1;
211 			goto again;
212 		}
213 	}
214 	count = 0;
215 	if (mflag) {
216 		lookman(cp);
217 		if (uflag && print == 0 && count != 1) {
218 			print = 1;
219 			goto again;
220 		}
221 	}
222 	if (print)
223 		printf("\n");
224 }
225 
226 looksrc(cp)
227 	char *cp;
228 {
229 	if (Sflag == 0) {
230 		find(srcdirs, cp);
231 	} else
232 		findv(Sflag, Scnt, cp);
233 }
234 
235 lookbin(cp)
236 	char *cp;
237 {
238 	if (Bflag == 0)
239 		find(bindirs, cp);
240 	else
241 		findv(Bflag, Bcnt, cp);
242 }
243 
244 lookman(cp)
245 	char *cp;
246 {
247 	if (Mflag == 0) {
248 		find(mandirs, cp);
249 	} else
250 		findv(Mflag, Mcnt, cp);
251 }
252 
253 findv(dirv, dirc, cp)
254 	char **dirv;
255 	int dirc;
256 	char *cp;
257 {
258 
259 	while (dirc > 0)
260 		findin(*dirv++, cp), dirc--;
261 }
262 
263 find(dirs, cp)
264 	char **dirs;
265 	char *cp;
266 {
267 
268 	while (*dirs)
269 		findin(*dirs++, cp);
270 }
271 
272 findin(dir, cp)
273 	char *dir, *cp;
274 {
275 	register FILE *d;
276 	struct direct direct;
277 
278 	d = fopen(dir, "r");
279 	if (d == NULL)
280 		return;
281 	while (fread(&direct, sizeof direct, 1, d) == 1) {
282 		if (direct.d_ino == 0)
283 			continue;
284 		if (itsit(cp, direct.d_name)) {
285 			count++;
286 			if (print)
287 				printf(" %s/%.14s", dir, direct.d_name);
288 		}
289 	}
290 	fclose(d);
291 }
292 
293 itsit(cp, dp)
294 	register char *cp, *dp;
295 {
296 	register int i = 14;
297 
298 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
299 		return (1);
300 	while (*cp && *dp && *cp == *dp)
301 		cp++, dp++, i--;
302 	if (*cp == 0 && *dp == 0)
303 		return (1);
304 	while (isdigit(*dp))
305 		dp++;
306 	if (*cp == 0 && *dp++ == '.') {
307 		--i;
308 		while (i > 0 && *dp)
309 			if (--i, *dp++ == '.')
310 				return (*dp++ == 'C' && *dp++ == 0);
311 		return (1);
312 	}
313 	return (0);
314 }
315