xref: /onnv-gate/usr/src/ucbcmd/whereis/whereis.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate 
6*0Sstevel@tonic-gate /*
7*0Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
8*0Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
9*0Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
10*0Sstevel@tonic-gate  */
11*0Sstevel@tonic-gate 
12*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
13*0Sstevel@tonic-gate 
14*0Sstevel@tonic-gate 
15*0Sstevel@tonic-gate #include <sys/param.h>
16*0Sstevel@tonic-gate #include <dirent.h>
17*0Sstevel@tonic-gate #include <stdio.h>
18*0Sstevel@tonic-gate #include <ctype.h>
19*0Sstevel@tonic-gate 
20*0Sstevel@tonic-gate static char *bindirs[] = {
21*0Sstevel@tonic-gate 	"/etc",
22*0Sstevel@tonic-gate 	"/sbin",
23*0Sstevel@tonic-gate 	"/usr/bin",
24*0Sstevel@tonic-gate 	"/usr/ccs/bin",
25*0Sstevel@tonic-gate 	"/usr/ccs/lib",
26*0Sstevel@tonic-gate 	"/usr/lang",
27*0Sstevel@tonic-gate 	"/usr/lbin",
28*0Sstevel@tonic-gate 	"/usr/lib",
29*0Sstevel@tonic-gate 	"/usr/sbin",
30*0Sstevel@tonic-gate 	"/usr/ucb",
31*0Sstevel@tonic-gate 	"/usr/ucblib",
32*0Sstevel@tonic-gate 	"/usr/ucbinclude",
33*0Sstevel@tonic-gate 	"/usr/games",
34*0Sstevel@tonic-gate 	"/usr/local",
35*0Sstevel@tonic-gate 	"/usr/local/bin",
36*0Sstevel@tonic-gate 	"/usr/new",
37*0Sstevel@tonic-gate 	"/usr/old",
38*0Sstevel@tonic-gate 	"/usr/hosts",
39*0Sstevel@tonic-gate 	"/usr/include",
40*0Sstevel@tonic-gate 	"/usr/etc",
41*0Sstevel@tonic-gate 	0
42*0Sstevel@tonic-gate };
43*0Sstevel@tonic-gate static char *mandirs[] = {
44*0Sstevel@tonic-gate 	"/usr/man/man1",
45*0Sstevel@tonic-gate 	"/usr/man/man1b",
46*0Sstevel@tonic-gate 	"/usr/man/man1c",
47*0Sstevel@tonic-gate 	"/usr/man/man1f",
48*0Sstevel@tonic-gate 	"/usr/man/man1m",
49*0Sstevel@tonic-gate 	"/usr/man/man1s",
50*0Sstevel@tonic-gate 	"/usr/man/man2",
51*0Sstevel@tonic-gate 	"/usr/man/man3",
52*0Sstevel@tonic-gate 	"/usr/man/man3b",
53*0Sstevel@tonic-gate 	"/usr/man/man3c",
54*0Sstevel@tonic-gate 	"/usr/man/man3e",
55*0Sstevel@tonic-gate 	"/usr/man/man3g",
56*0Sstevel@tonic-gate 	"/usr/man/man3j",
57*0Sstevel@tonic-gate 	"/usr/man/man3k",
58*0Sstevel@tonic-gate 	"/usr/man/man3l",
59*0Sstevel@tonic-gate 	"/usr/man/man3m",
60*0Sstevel@tonic-gate 	"/usr/man/man3n",
61*0Sstevel@tonic-gate 	"/usr/man/man3s",
62*0Sstevel@tonic-gate 	"/usr/man/man3w",
63*0Sstevel@tonic-gate 	"/usr/man/man3x",
64*0Sstevel@tonic-gate 	"/usr/man/man3x11",
65*0Sstevel@tonic-gate 	"/usr/man/man3xt",
66*0Sstevel@tonic-gate 	"/usr/man/man4",
67*0Sstevel@tonic-gate 	"/usr/man/man4b",
68*0Sstevel@tonic-gate 	"/usr/man/man5",
69*0Sstevel@tonic-gate 	"/usr/man/man6",
70*0Sstevel@tonic-gate 	"/usr/man/man7",
71*0Sstevel@tonic-gate 	"/usr/man/man7b",
72*0Sstevel@tonic-gate 	"/usr/man/man8",
73*0Sstevel@tonic-gate 	"/usr/man/man9e",
74*0Sstevel@tonic-gate 	"/usr/man/man9f",
75*0Sstevel@tonic-gate 	"/usr/man/man9s",
76*0Sstevel@tonic-gate 	"/usr/man/manl",
77*0Sstevel@tonic-gate 	"/usr/man/mann",
78*0Sstevel@tonic-gate 	"/usr/man/mano",
79*0Sstevel@tonic-gate 	0
80*0Sstevel@tonic-gate };
81*0Sstevel@tonic-gate static char *srcdirs[]  = {
82*0Sstevel@tonic-gate 	"/usr/src/cmd",
83*0Sstevel@tonic-gate 	"/usr/src/head",
84*0Sstevel@tonic-gate 	"/usr/src/lib",
85*0Sstevel@tonic-gate 	"/usr/src/lib/libc",
86*0Sstevel@tonic-gate 	"/usr/src/lib/libc/port",
87*0Sstevel@tonic-gate 	"/usr/src/lib/libc/port/gen",
88*0Sstevel@tonic-gate 	"/usr/src/lib/libc/port/print",
89*0Sstevel@tonic-gate 	"/usr/src/lib/libc/port/stdio",
90*0Sstevel@tonic-gate 	"/usr/src/lib/libc/port/sys",
91*0Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc",
92*0Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/gen",
93*0Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/sys",
94*0Sstevel@tonic-gate 	"/usr/src/ucbcmd",
95*0Sstevel@tonic-gate 	"/usr/src/ucblib",
96*0Sstevel@tonic-gate 	"/usr/src/ucbinclude",
97*0Sstevel@tonic-gate 	"/usr/src/uts",
98*0Sstevel@tonic-gate 	"/usr/src/uts/common",
99*0Sstevel@tonic-gate 	"/usr/src/uts/sun",
100*0Sstevel@tonic-gate 	"/usr/src/uts/sun4",
101*0Sstevel@tonic-gate 	"/usr/src/uts/sun4c",
102*0Sstevel@tonic-gate 	"/usr/src/uts/sparc",
103*0Sstevel@tonic-gate 	"/usr/src/local",
104*0Sstevel@tonic-gate 	"/usr/src/new",
105*0Sstevel@tonic-gate 	"/usr/src/old",
106*0Sstevel@tonic-gate 	0
107*0Sstevel@tonic-gate };
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate char	sflag = 1;
110*0Sstevel@tonic-gate char	bflag = 1;
111*0Sstevel@tonic-gate char	mflag = 1;
112*0Sstevel@tonic-gate char	**Sflag;
113*0Sstevel@tonic-gate int	Scnt;
114*0Sstevel@tonic-gate char	**Bflag;
115*0Sstevel@tonic-gate int	Bcnt;
116*0Sstevel@tonic-gate char	**Mflag;
117*0Sstevel@tonic-gate int	Mcnt;
118*0Sstevel@tonic-gate char	uflag;
119*0Sstevel@tonic-gate /*
120*0Sstevel@tonic-gate  * whereis name
121*0Sstevel@tonic-gate  * look for source, documentation and binaries
122*0Sstevel@tonic-gate  */
123*0Sstevel@tonic-gate main(argc, argv)
124*0Sstevel@tonic-gate 	int argc;
125*0Sstevel@tonic-gate 	char *argv[];
126*0Sstevel@tonic-gate {
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 	argc--, argv++;
129*0Sstevel@tonic-gate 	if (argc == 0) {
130*0Sstevel@tonic-gate usage:
131*0Sstevel@tonic-gate 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
132*0Sstevel@tonic-gate 		exit(1);
133*0Sstevel@tonic-gate 	}
134*0Sstevel@tonic-gate 	do
135*0Sstevel@tonic-gate 		if (argv[0][0] == '-') {
136*0Sstevel@tonic-gate 			register char *cp = argv[0] + 1;
137*0Sstevel@tonic-gate 			while (*cp) switch (*cp++) {
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 			case 'f':
140*0Sstevel@tonic-gate 				break;
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 			case 'S':
143*0Sstevel@tonic-gate 				getlist(&argc, &argv, &Sflag, &Scnt);
144*0Sstevel@tonic-gate 				break;
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 			case 'B':
147*0Sstevel@tonic-gate 				getlist(&argc, &argv, &Bflag, &Bcnt);
148*0Sstevel@tonic-gate 				break;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 			case 'M':
151*0Sstevel@tonic-gate 				getlist(&argc, &argv, &Mflag, &Mcnt);
152*0Sstevel@tonic-gate 				break;
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 			case 's':
155*0Sstevel@tonic-gate 				zerof();
156*0Sstevel@tonic-gate 				sflag++;
157*0Sstevel@tonic-gate 				continue;
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 			case 'u':
160*0Sstevel@tonic-gate 				uflag++;
161*0Sstevel@tonic-gate 				continue;
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate 			case 'b':
164*0Sstevel@tonic-gate 				zerof();
165*0Sstevel@tonic-gate 				bflag++;
166*0Sstevel@tonic-gate 				continue;
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 			case 'm':
169*0Sstevel@tonic-gate 				zerof();
170*0Sstevel@tonic-gate 				mflag++;
171*0Sstevel@tonic-gate 				continue;
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 			default:
174*0Sstevel@tonic-gate 				goto usage;
175*0Sstevel@tonic-gate 			}
176*0Sstevel@tonic-gate 			argv++;
177*0Sstevel@tonic-gate 		} else
178*0Sstevel@tonic-gate 			lookup(*argv++);
179*0Sstevel@tonic-gate 	while (--argc > 0);
180*0Sstevel@tonic-gate 	exit(0);
181*0Sstevel@tonic-gate 	/* NOTREACHED */
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate getlist(argcp, argvp, flagp, cntp)
185*0Sstevel@tonic-gate 	char ***argvp;
186*0Sstevel@tonic-gate 	int *argcp;
187*0Sstevel@tonic-gate 	char ***flagp;
188*0Sstevel@tonic-gate 	int *cntp;
189*0Sstevel@tonic-gate {
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	(*argvp)++;
192*0Sstevel@tonic-gate 	*flagp = *argvp;
193*0Sstevel@tonic-gate 	*cntp = 0;
194*0Sstevel@tonic-gate 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
195*0Sstevel@tonic-gate 		(*cntp)++, (*argvp)++;
196*0Sstevel@tonic-gate 	(*argcp)++;
197*0Sstevel@tonic-gate 	(*argvp)--;
198*0Sstevel@tonic-gate }
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate zerof()
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	if (sflag && bflag && mflag)
205*0Sstevel@tonic-gate 		sflag = bflag = mflag = 0;
206*0Sstevel@tonic-gate }
207*0Sstevel@tonic-gate int	count;
208*0Sstevel@tonic-gate int	print;
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate lookup(cp)
212*0Sstevel@tonic-gate 	register char *cp;
213*0Sstevel@tonic-gate {
214*0Sstevel@tonic-gate 	register char *dp;
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
217*0Sstevel@tonic-gate 		continue;
218*0Sstevel@tonic-gate 	for (; dp > cp; dp--) {
219*0Sstevel@tonic-gate 		if (*dp == '.') {
220*0Sstevel@tonic-gate 			*dp = 0;
221*0Sstevel@tonic-gate 			break;
222*0Sstevel@tonic-gate 		}
223*0Sstevel@tonic-gate 	}
224*0Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
225*0Sstevel@tonic-gate 		if (*dp == '/')
226*0Sstevel@tonic-gate 			cp = dp + 1;
227*0Sstevel@tonic-gate 	if (uflag) {
228*0Sstevel@tonic-gate 		print = 0;
229*0Sstevel@tonic-gate 		count = 0;
230*0Sstevel@tonic-gate 	} else
231*0Sstevel@tonic-gate 		print = 1;
232*0Sstevel@tonic-gate again:
233*0Sstevel@tonic-gate 	if (print)
234*0Sstevel@tonic-gate 		printf("%s:", cp);
235*0Sstevel@tonic-gate 	if (sflag) {
236*0Sstevel@tonic-gate 		looksrc(cp);
237*0Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
238*0Sstevel@tonic-gate 			print = 1;
239*0Sstevel@tonic-gate 			goto again;
240*0Sstevel@tonic-gate 		}
241*0Sstevel@tonic-gate 	}
242*0Sstevel@tonic-gate 	count = 0;
243*0Sstevel@tonic-gate 	if (bflag) {
244*0Sstevel@tonic-gate 		lookbin(cp);
245*0Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
246*0Sstevel@tonic-gate 			print = 1;
247*0Sstevel@tonic-gate 			goto again;
248*0Sstevel@tonic-gate 		}
249*0Sstevel@tonic-gate 	}
250*0Sstevel@tonic-gate 	count = 0;
251*0Sstevel@tonic-gate 	if (mflag) {
252*0Sstevel@tonic-gate 		lookman(cp);
253*0Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
254*0Sstevel@tonic-gate 			print = 1;
255*0Sstevel@tonic-gate 			goto again;
256*0Sstevel@tonic-gate 		}
257*0Sstevel@tonic-gate 	}
258*0Sstevel@tonic-gate 	if (print)
259*0Sstevel@tonic-gate 		printf("\n");
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate looksrc(cp)
263*0Sstevel@tonic-gate 	char *cp;
264*0Sstevel@tonic-gate {
265*0Sstevel@tonic-gate 	if (Sflag == 0) {
266*0Sstevel@tonic-gate 		find(srcdirs, cp);
267*0Sstevel@tonic-gate 	} else
268*0Sstevel@tonic-gate 		findv(Sflag, Scnt, cp);
269*0Sstevel@tonic-gate }
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate lookbin(cp)
272*0Sstevel@tonic-gate 	char *cp;
273*0Sstevel@tonic-gate {
274*0Sstevel@tonic-gate 	if (Bflag == 0)
275*0Sstevel@tonic-gate 		find(bindirs, cp);
276*0Sstevel@tonic-gate 	else
277*0Sstevel@tonic-gate 		findv(Bflag, Bcnt, cp);
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate lookman(cp)
281*0Sstevel@tonic-gate 	char *cp;
282*0Sstevel@tonic-gate {
283*0Sstevel@tonic-gate 	if (Mflag == 0) {
284*0Sstevel@tonic-gate 		find(mandirs, cp);
285*0Sstevel@tonic-gate 	} else
286*0Sstevel@tonic-gate 		findv(Mflag, Mcnt, cp);
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate findv(dirv, dirc, cp)
290*0Sstevel@tonic-gate 	char **dirv;
291*0Sstevel@tonic-gate 	int dirc;
292*0Sstevel@tonic-gate 	char *cp;
293*0Sstevel@tonic-gate {
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 	while (dirc > 0)
296*0Sstevel@tonic-gate 		findin(*dirv++, cp), dirc--;
297*0Sstevel@tonic-gate }
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate find(dirs, cp)
300*0Sstevel@tonic-gate 	char **dirs;
301*0Sstevel@tonic-gate 	char *cp;
302*0Sstevel@tonic-gate {
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 	while (*dirs)
305*0Sstevel@tonic-gate 		findin(*dirs++, cp);
306*0Sstevel@tonic-gate }
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate findin(dir, cp)
309*0Sstevel@tonic-gate 	char *dir, *cp;
310*0Sstevel@tonic-gate {
311*0Sstevel@tonic-gate 	DIR *dirp;
312*0Sstevel@tonic-gate 	struct dirent *dp;
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 	dirp = opendir(dir);
315*0Sstevel@tonic-gate 	if (dirp == NULL)
316*0Sstevel@tonic-gate 		return;
317*0Sstevel@tonic-gate 	while ((dp = readdir(dirp)) != NULL) {
318*0Sstevel@tonic-gate 		if (itsit(cp, dp->d_name)) {
319*0Sstevel@tonic-gate 			count++;
320*0Sstevel@tonic-gate 			if (print)
321*0Sstevel@tonic-gate 				printf(" %s/%s", dir, dp->d_name);
322*0Sstevel@tonic-gate 		}
323*0Sstevel@tonic-gate 	}
324*0Sstevel@tonic-gate 	closedir(dirp);
325*0Sstevel@tonic-gate }
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate itsit(cp, dp)
328*0Sstevel@tonic-gate 	register char *cp, *dp;
329*0Sstevel@tonic-gate {
330*0Sstevel@tonic-gate 	register int i = strlen(dp);
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
333*0Sstevel@tonic-gate 		return (1);
334*0Sstevel@tonic-gate 	while (*cp && *dp && *cp == *dp)
335*0Sstevel@tonic-gate 		cp++, dp++, i--;
336*0Sstevel@tonic-gate 	if (*cp == 0 && *dp == 0)
337*0Sstevel@tonic-gate 		return (1);
338*0Sstevel@tonic-gate 	while (isdigit(*dp))
339*0Sstevel@tonic-gate 		dp++;
340*0Sstevel@tonic-gate 	if (*cp == 0 && *dp++ == '.') {
341*0Sstevel@tonic-gate 		--i;
342*0Sstevel@tonic-gate 		while (i > 0 && *dp)
343*0Sstevel@tonic-gate 			if (--i, *dp++ == '.')
344*0Sstevel@tonic-gate 				return (*dp++ == 'C' && *dp++ == 0);
345*0Sstevel@tonic-gate 		return (1);
346*0Sstevel@tonic-gate 	}
347*0Sstevel@tonic-gate 	return (0);
348*0Sstevel@tonic-gate }
349