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