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