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