BSD 2 development
[unix-history] / src / whereis.c
CommitLineData
01995545
BJ
1/* Copyright (c) 1979 Regents of the University of California */
2#include <sys/types.h>
3#include <stdio.h>
4#include <ctype.h>
5#include <sys/dir.h>
6
7static char *bindirs[] = {
8 "/etc",
9 "/bin",
10 "/usr/bin",
11 "/usr/new",
12 "/usr/games",
13 0
14};
15static char *mandirs[] = {
16 "man1",
17 "man2",
18 "man3",
19 "man4",
20 "man5",
21 "man6",
22 "man7",
23 "man8",
24 "mann",
25 "127local",
26 0
27};
28static char *srcdirs[] = {
29 "cmd",
30 "libc/gen",
31 "libc/stdio",
32 "games",
33 "/usr/ucb/src/cmd",
34 "/usr/ucb/src/new",
35 "/usr/ucb/src/libc/gen",
36 "/usr/ucb/src/libc/stdio",
37 0
38};
39char sflag = 1;
40char bflag = 1;
41char mflag = 1;
42char **Sflag;
43int Scnt;
44char **Bflag;
45int Bcnt;
46char **Mflag;
47int Mcnt;
48char uflag;
49/*
50 * whereis name
51 * look for source, documentation and binaries
52 */
53main(argc, argv)
54 int argc;
55 char *argv[];
56{
57
58#ifdef CORY
59 if (getuid() == 0)
60 nice(-20);
61 if (((getuid() >> 8) & 0377) > 10)
62 setuid(getuid());
63#endif
64 argc--, argv++;
65 if (argc == 0) {
66usage:
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
118getlist(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
135zerof()
136{
137
138 if (sflag && bflag && mflag)
139 sflag = bflag = mflag = 0;
140}
141int count;
142int print;
143
144
145lookup(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;
166again:
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
196looksrc(cp)
197 char *cp;
198{
199 if (Sflag == 0) {
200 chdir("/usr/src");
201 find(srcdirs, cp);
202 } else
203 findv(Sflag, Scnt, cp);
204}
205
206lookbin(cp)
207 char *cp;
208{
209 if (Bflag == 0)
210 find(bindirs, cp);
211 else
212 findv(Bflag, Bcnt, cp);
213}
214
215lookman(cp)
216 char *cp;
217{
218 if (Mflag == 0) {
219 chdir("/usr/man");
220 find(mandirs, cp);
221 } else
222 findv(Mflag, Mcnt, cp);
223}
224
225findv(dirv, dirc, cp)
226 char **dirv;
227 int dirc;
228 char *cp;
229{
230
231 while (dirc > 0)
232 findin(*dirv++, cp), dirc--;
233}
234
235find(dirs, cp)
236 char **dirs;
237 char *cp;
238{
239
240 while (*dirs)
241 findin(*dirs++, cp);
242}
243
244findin(dir, cp)
245 char *dir, *cp;
246{
247 register FILE *d;
248 struct direct direct;
249
250 d = fopen(dir, "r");
251 if (d == NULL)
252 return;
253 while (fread(&direct, sizeof direct, 1, d) == 1) {
254 if (direct.d_ino == 0)
255 continue;
256 if (itsit(cp, direct.d_name)) {
257 count++;
258 if (print)
259 printf(" %s/%.14s", dir, direct.d_name);
260 }
261 }
262 fclose(d);
263}
264
265itsit(cp, dp)
266 register char *cp, *dp;
267{
268 register int i = 14;
269
270 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
271 return (1);
272 while (*cp && *dp && *cp == *dp)
273 cp++, dp++, i--;
274 if (*cp == 0 && *dp == 0)
275 return (1);
276 while (isdigit(*dp))
277 dp++;
278 if (*cp == 0 && *dp++ == '.') {
279 --i;
280 while (i > 0 && *dp)
281 if (--i, *dp++ == '.')
282 return (*dp++ == 'P' && *dp++ == 0);
283 return (1);
284 }
285 return (0);
286}