xref: /original-bsd/old/whereis/whereis.c (revision a304ca22)
1 static char *sccsid = "@(#)whereis.c	4.5 (Berkeley) 03/15/82";
2 
3 #include <sys/types.h>
4 #include <stdio.h>
5 #include <ctype.h>
6 #include <sys/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 	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 	argc--, argv++;
65 	if (argc == 0) {
66 usage:
67 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
68 		exit(1);
69 	}
70 	do
71 		if (argv[0][0] == '-') {
72 			register char *cp = argv[0] + 1;
73 			while (*cp) switch (*cp++) {
74 
75 			case 'f':
76 				break;
77 
78 			case 'S':
79 				getlist(&argc, &argv, &Sflag, &Scnt);
80 				break;
81 
82 			case 'B':
83 				getlist(&argc, &argv, &Bflag, &Bcnt);
84 				break;
85 
86 			case 'M':
87 				getlist(&argc, &argv, &Mflag, &Mcnt);
88 				break;
89 
90 			case 's':
91 				zerof();
92 				sflag++;
93 				continue;
94 
95 			case 'u':
96 				uflag++;
97 				continue;
98 
99 			case 'b':
100 				zerof();
101 				bflag++;
102 				continue;
103 
104 			case 'm':
105 				zerof();
106 				mflag++;
107 				continue;
108 
109 			default:
110 				goto usage;
111 			}
112 			argv++;
113 		} else
114 			lookup(*argv++);
115 	while (--argc > 0);
116 }
117 
118 getlist(argcp, argvp, flagp, cntp)
119 	char ***argvp;
120 	int *argcp;
121 	char ***flagp;
122 	int *cntp;
123 {
124 
125 	(*argvp)++;
126 	*flagp = *argvp;
127 	*cntp = 0;
128 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
129 		(*cntp)++, (*argvp)++;
130 	(*argcp)++;
131 	(*argvp)--;
132 }
133 
134 
135 zerof()
136 {
137 
138 	if (sflag && bflag && mflag)
139 		sflag = bflag = mflag = 0;
140 }
141 int	count;
142 int	print;
143 
144 
145 lookup(cp)
146 	register char *cp;
147 {
148 	register char *dp;
149 
150 	for (dp = cp; *dp; dp++)
151 		continue;
152 	for (; dp > cp; dp--) {
153 		if (*dp == '.') {
154 			*dp = 0;
155 			break;
156 		}
157 	}
158 	for (dp = cp; *dp; dp++)
159 		if (*dp == '/')
160 			cp = dp + 1;
161 	if (uflag) {
162 		print = 0;
163 		count = 0;
164 	} else
165 		print = 1;
166 again:
167 	if (print)
168 		printf("%s:", cp);
169 	if (sflag) {
170 		looksrc(cp);
171 		if (uflag && print == 0 && count != 1) {
172 			print = 1;
173 			goto again;
174 		}
175 	}
176 	count = 0;
177 	if (bflag) {
178 		lookbin(cp);
179 		if (uflag && print == 0 && count != 1) {
180 			print = 1;
181 			goto again;
182 		}
183 	}
184 	count = 0;
185 	if (mflag) {
186 		lookman(cp);
187 		if (uflag && print == 0 && count != 1) {
188 			print = 1;
189 			goto again;
190 		}
191 	}
192 	if (print)
193 		printf("\n");
194 }
195 
196 looksrc(cp)
197 	char *cp;
198 {
199 	if (Sflag == 0) {
200 		find(srcdirs, cp);
201 	} else
202 		findv(Sflag, Scnt, cp);
203 }
204 
205 lookbin(cp)
206 	char *cp;
207 {
208 	if (Bflag == 0)
209 		find(bindirs, cp);
210 	else
211 		findv(Bflag, Bcnt, cp);
212 }
213 
214 lookman(cp)
215 	char *cp;
216 {
217 	if (Mflag == 0) {
218 		find(mandirs, cp);
219 	} else
220 		findv(Mflag, Mcnt, cp);
221 }
222 
223 findv(dirv, dirc, cp)
224 	char **dirv;
225 	int dirc;
226 	char *cp;
227 {
228 
229 	while (dirc > 0)
230 		findin(*dirv++, cp), dirc--;
231 }
232 
233 find(dirs, cp)
234 	char **dirs;
235 	char *cp;
236 {
237 
238 	while (*dirs)
239 		findin(*dirs++, cp);
240 }
241 
242 findin(dir, cp)
243 	char *dir, *cp;
244 {
245 	register FILE *d;
246 	struct direct direct;
247 
248 	d = fopen(dir, "r");
249 	if (d == NULL)
250 		return;
251 	while (fread(&direct, sizeof direct, 1, d) == 1) {
252 		if (direct.d_ino == 0)
253 			continue;
254 		if (itsit(cp, direct.d_name)) {
255 			count++;
256 			if (print)
257 				printf(" %s/%.14s", dir, direct.d_name);
258 		}
259 	}
260 	fclose(d);
261 }
262 
263 itsit(cp, dp)
264 	register char *cp, *dp;
265 {
266 	register int i = 14;
267 
268 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
269 		return (1);
270 	while (*cp && *dp && *cp == *dp)
271 		cp++, dp++, i--;
272 	if (*cp == 0 && *dp == 0)
273 		return (1);
274 	while (isdigit(*dp))
275 		dp++;
276 	if (*cp == 0 && *dp++ == '.') {
277 		--i;
278 		while (i > 0 && *dp)
279 			if (--i, *dp++ == '.')
280 				return (*dp++ == 'C' && *dp++ == 0);
281 		return (1);
282 	}
283 	return (0);
284 }
285