]> git.ipfire.org Git - thirdparty/util-linux.git/blame - misc-utils/whereis.c
Imported from util-linux-2.8 tarball.
[thirdparty/util-linux.git] / misc-utils / whereis.c
CommitLineData
6dbe3af9
KZ
1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
2b6fc908 34/* *:aeb */
6dbe3af9
KZ
35
36#include <sys/param.h>
37#include <sys/dir.h>
2b6fc908 38#include <sys/stat.h>
6dbe3af9 39#include <stdio.h>
fd6b7a7f 40#include <string.h>
6dbe3af9
KZ
41#include <ctype.h>
42
fd6b7a7f
KZ
43void zerof(void);
44void getlist(int *, char ***, char ***, int *);
45void lookup(char *);
46void looksrc(char *);
47void lookbin(char *);
48void lookman(char *);
49void findv(char **, int, char *);
50void find(char **, char *);
51void findin(char *, char *);
52int itsit(char *, char *);
53
6dbe3af9 54static char *bindirs[] = {
6dbe3af9
KZ
55 "/bin",
56 "/usr/bin",
6dbe3af9
KZ
57 "/sbin",
58 "/usr/sbin",
2b6fc908
KZ
59 "/etc",
60 "/usr/etc",
61 "/lib",
62 "/usr/lib",
6dbe3af9
KZ
63 "/usr/games",
64 "/usr/games/bin",
2b6fc908 65 "/usr/games/lib",
6dbe3af9 66 "/usr/emacs/etc",
2b6fc908 67 "/usr/lib/emacs/*/etc",
6dbe3af9
KZ
68 "/usr/TeX/bin",
69 "/usr/tex/bin",
70 "/usr/interviews/bin/LINUX",
71
2b6fc908
KZ
72 "/usr/X11R6/bin",
73 "/usr/X386/bin",
6dbe3af9
KZ
74 "/usr/bin/X11",
75 "/usr/X11/bin",
76 "/usr/X11R5/bin",
6dbe3af9
KZ
77
78 "/usr/local/bin",
6dbe3af9 79 "/usr/local/sbin",
2b6fc908
KZ
80 "/usr/local/etc",
81 "/usr/local/lib",
6dbe3af9
KZ
82 "/usr/local/games",
83 "/usr/local/games/bin",
84 "/usr/local/emacs/etc",
85 "/usr/local/TeX/bin",
86 "/usr/local/tex/bin",
87 "/usr/local/bin/X11",
88
89 "/usr/contrib",
90 "/usr/hosts",
91 "/usr/include",
92
93 "/usr/g++-include",
2b6fc908
KZ
94
95 "/usr/ucb",
96 "/usr/old",
97 "/usr/new",
98 "/usr/local",
99 "/usr/libexec",
100 "/usr/share",
101
6dbe3af9
KZ
102 0
103};
2b6fc908 104
6dbe3af9 105static char *mandirs[] = {
2b6fc908
KZ
106 "/usr/man/*",
107 "/usr/X386/man/*",
108 "/usr/X11/man/*",
109 "/usr/TeX/man/*",
6dbe3af9 110 "/usr/interviews/man/mann",
6dbe3af9
KZ
111 0
112};
2b6fc908 113
6dbe3af9 114static char *srcdirs[] = {
2b6fc908
KZ
115 "/usr/src/*",
116 "/usr/src/lib/libc/*",
117 "/usr/src/lib/libc/net/*",
6dbe3af9
KZ
118 "/usr/src/ucb/pascal",
119 "/usr/src/ucb/pascal/utilities",
120 "/usr/src/undoc",
6dbe3af9
KZ
121 0
122};
123
124char sflag = 1;
125char bflag = 1;
126char mflag = 1;
127char **Sflag;
128int Scnt;
129char **Bflag;
130int Bcnt;
131char **Mflag;
132int Mcnt;
133char uflag;
134/*
135 * whereis name
136 * look for source, documentation and binaries
137 */
fd6b7a7f 138int
6dbe3af9
KZ
139main(argc, argv)
140 int argc;
141 char *argv[];
142{
143
144 argc--, argv++;
145 if (argc == 0) {
146usage:
147 fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
148 exit(1);
149 }
150 do
151 if (argv[0][0] == '-') {
152 register char *cp = argv[0] + 1;
153 while (*cp) switch (*cp++) {
154
155 case 'f':
156 break;
157
158 case 'S':
159 getlist(&argc, &argv, &Sflag, &Scnt);
160 break;
161
162 case 'B':
163 getlist(&argc, &argv, &Bflag, &Bcnt);
164 break;
165
166 case 'M':
167 getlist(&argc, &argv, &Mflag, &Mcnt);
168 break;
169
170 case 's':
171 zerof();
172 sflag++;
173 continue;
174
175 case 'u':
176 uflag++;
177 continue;
178
179 case 'b':
180 zerof();
181 bflag++;
182 continue;
183
184 case 'm':
185 zerof();
186 mflag++;
187 continue;
188
189 default:
190 goto usage;
191 }
192 argv++;
193 } else
194 lookup(*argv++);
195 while (--argc > 0);
fd6b7a7f 196 return 0;
6dbe3af9
KZ
197}
198
fd6b7a7f 199void
2b6fc908 200getlist(int *argcp, char ***argvp, char ***flagp, int *cntp) {
6dbe3af9
KZ
201 (*argvp)++;
202 *flagp = *argvp;
203 *cntp = 0;
204 for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
205 (*cntp)++, (*argvp)++;
206 (*argcp)++;
207 (*argvp)--;
208}
209
210
fd6b7a7f 211void
6dbe3af9
KZ
212zerof()
213{
6dbe3af9
KZ
214 if (sflag && bflag && mflag)
215 sflag = bflag = mflag = 0;
216}
fd6b7a7f 217
6dbe3af9
KZ
218int count;
219int print;
220
fd6b7a7f 221void
2b6fc908 222lookup(char *cp) {
6dbe3af9
KZ
223 register char *dp;
224
225 for (dp = cp; *dp; dp++)
226 continue;
227 for (; dp > cp; dp--) {
228 if (*dp == '.') {
229 *dp = 0;
230 break;
231 }
232 }
233 for (dp = cp; *dp; dp++)
234 if (*dp == '/')
235 cp = dp + 1;
236 if (uflag) {
237 print = 0;
238 count = 0;
239 } else
240 print = 1;
241again:
242 if (print)
243 printf("%s:", cp);
244 if (sflag) {
245 looksrc(cp);
246 if (uflag && print == 0 && count != 1) {
247 print = 1;
248 goto again;
249 }
250 }
251 count = 0;
252 if (bflag) {
253 lookbin(cp);
254 if (uflag && print == 0 && count != 1) {
255 print = 1;
256 goto again;
257 }
258 }
259 count = 0;
260 if (mflag) {
261 lookman(cp);
262 if (uflag && print == 0 && count != 1) {
263 print = 1;
264 goto again;
265 }
266 }
267 if (print)
268 printf("\n");
269}
270
fd6b7a7f 271void
2b6fc908 272looksrc(char *cp) {
6dbe3af9
KZ
273 if (Sflag == 0) {
274 find(srcdirs, cp);
275 } else
276 findv(Sflag, Scnt, cp);
277}
278
fd6b7a7f 279void
2b6fc908 280lookbin(char *cp) {
6dbe3af9
KZ
281 if (Bflag == 0)
282 find(bindirs, cp);
283 else
284 findv(Bflag, Bcnt, cp);
285}
286
fd6b7a7f 287void
2b6fc908 288lookman(char *cp) {
6dbe3af9
KZ
289 if (Mflag == 0) {
290 find(mandirs, cp);
291 } else
292 findv(Mflag, Mcnt, cp);
293}
294
fd6b7a7f 295void
2b6fc908 296findv(char **dirv, int dirc, char *cp) {
6dbe3af9
KZ
297 while (dirc > 0)
298 findin(*dirv++, cp), dirc--;
299}
300
fd6b7a7f 301void
2b6fc908 302find(char **dirs, char *cp) {
6dbe3af9
KZ
303 while (*dirs)
304 findin(*dirs++, cp);
305}
306
fd6b7a7f 307void
2b6fc908 308findin(char *dir, char *cp) {
6dbe3af9
KZ
309 DIR *dirp;
310 struct direct *dp;
2b6fc908
KZ
311 char *d, *dd;
312 int l;
313 char dirbuf[1024];
314 struct stat statbuf;
315
316 dd = index(dir, '*');
317 if (!dd)
318 goto noglob;
319
320 l = strlen(dir);
321 if (l < sizeof(dirbuf)) { /* refuse excessively long names */
322 strcpy (dirbuf, dir);
323 d = index(dirbuf, '*');
324 *d = 0;
325 dirp = opendir(dirbuf);
326 if (dirp == NULL)
327 return;
328 while ((dp = readdir(dirp)) != NULL) {
329 if (strlen(dp->d_name) + l > sizeof(dirbuf))
330 continue;
331 sprintf(d, "%s", dp->d_name);
332 if (stat(dirbuf, &statbuf))
333 continue;
334 if (!S_ISDIR(statbuf.st_mode))
335 continue;
336 strcat(d, dd+1);
337 findin(dirbuf, cp);
338 }
339 closedir(dirp);
340 }
341 return;
6dbe3af9 342
2b6fc908 343 noglob:
6dbe3af9
KZ
344 dirp = opendir(dir);
345 if (dirp == NULL)
346 return;
347 while ((dp = readdir(dirp)) != NULL) {
348 if (itsit(cp, dp->d_name)) {
349 count++;
350 if (print)
351 printf(" %s/%s", dir, dp->d_name);
352 }
353 }
354 closedir(dirp);
355}
356
fd6b7a7f 357int
2b6fc908
KZ
358itsit(char *cp, char *dp) {
359 int i = strlen(dp);
6dbe3af9
KZ
360
361 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
362 return (1);
2b6fc908
KZ
363 if (!strcmp(dp+i-2, ".Z"))
364 i -= 2;
365 else if (!strcmp(dp+i-3, ".gz"))
366 i -= 3;
367 else if (!strcmp(dp+i-4, ".bz2"))
368 i -= 4;
6dbe3af9
KZ
369 while (*cp && *dp && *cp == *dp)
370 cp++, dp++, i--;
371 if (*cp == 0 && *dp == 0)
372 return (1);
373 while (isdigit(*dp))
374 dp++;
375 if (*cp == 0 && *dp++ == '.') {
376 --i;
377 while (i > 0 && *dp)
378 if (--i, *dp++ == '.')
379 return (*dp++ == 'C' && *dp++ == 0);
380 return (1);
381 }
382 return (0);
383}