xref: /onnv-gate/usr/src/ucbcmd/whereis/whereis.c (revision 669:3cf64fd04122)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
80Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
90Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
100Sstevel@tonic-gate  */
110Sstevel@tonic-gate 
120Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
130Sstevel@tonic-gate 
140Sstevel@tonic-gate 
150Sstevel@tonic-gate #include <sys/param.h>
160Sstevel@tonic-gate #include <dirent.h>
170Sstevel@tonic-gate #include <stdio.h>
180Sstevel@tonic-gate #include <ctype.h>
190Sstevel@tonic-gate 
200Sstevel@tonic-gate static char *bindirs[] = {
210Sstevel@tonic-gate 	"/etc",
220Sstevel@tonic-gate 	"/sbin",
230Sstevel@tonic-gate 	"/usr/bin",
240Sstevel@tonic-gate 	"/usr/ccs/bin",
250Sstevel@tonic-gate 	"/usr/ccs/lib",
260Sstevel@tonic-gate 	"/usr/lang",
270Sstevel@tonic-gate 	"/usr/lbin",
280Sstevel@tonic-gate 	"/usr/lib",
290Sstevel@tonic-gate 	"/usr/sbin",
300Sstevel@tonic-gate 	"/usr/ucb",
310Sstevel@tonic-gate 	"/usr/ucblib",
320Sstevel@tonic-gate 	"/usr/ucbinclude",
330Sstevel@tonic-gate 	"/usr/games",
340Sstevel@tonic-gate 	"/usr/local",
350Sstevel@tonic-gate 	"/usr/local/bin",
360Sstevel@tonic-gate 	"/usr/new",
370Sstevel@tonic-gate 	"/usr/old",
380Sstevel@tonic-gate 	"/usr/hosts",
390Sstevel@tonic-gate 	"/usr/include",
400Sstevel@tonic-gate 	"/usr/etc",
410Sstevel@tonic-gate 	0
420Sstevel@tonic-gate };
430Sstevel@tonic-gate static char *mandirs[] = {
440Sstevel@tonic-gate 	"/usr/man/man1",
450Sstevel@tonic-gate 	"/usr/man/man1b",
460Sstevel@tonic-gate 	"/usr/man/man1c",
470Sstevel@tonic-gate 	"/usr/man/man1f",
480Sstevel@tonic-gate 	"/usr/man/man1m",
490Sstevel@tonic-gate 	"/usr/man/man1s",
500Sstevel@tonic-gate 	"/usr/man/man2",
510Sstevel@tonic-gate 	"/usr/man/man3",
520Sstevel@tonic-gate 	"/usr/man/man3b",
530Sstevel@tonic-gate 	"/usr/man/man3c",
540Sstevel@tonic-gate 	"/usr/man/man3e",
550Sstevel@tonic-gate 	"/usr/man/man3g",
560Sstevel@tonic-gate 	"/usr/man/man3j",
570Sstevel@tonic-gate 	"/usr/man/man3k",
580Sstevel@tonic-gate 	"/usr/man/man3l",
590Sstevel@tonic-gate 	"/usr/man/man3m",
600Sstevel@tonic-gate 	"/usr/man/man3n",
610Sstevel@tonic-gate 	"/usr/man/man3s",
620Sstevel@tonic-gate 	"/usr/man/man3w",
630Sstevel@tonic-gate 	"/usr/man/man3x",
640Sstevel@tonic-gate 	"/usr/man/man3x11",
650Sstevel@tonic-gate 	"/usr/man/man3xt",
660Sstevel@tonic-gate 	"/usr/man/man4",
670Sstevel@tonic-gate 	"/usr/man/man4b",
680Sstevel@tonic-gate 	"/usr/man/man5",
690Sstevel@tonic-gate 	"/usr/man/man6",
700Sstevel@tonic-gate 	"/usr/man/man7",
710Sstevel@tonic-gate 	"/usr/man/man7b",
720Sstevel@tonic-gate 	"/usr/man/man8",
730Sstevel@tonic-gate 	"/usr/man/man9e",
740Sstevel@tonic-gate 	"/usr/man/man9f",
750Sstevel@tonic-gate 	"/usr/man/man9s",
760Sstevel@tonic-gate 	"/usr/man/manl",
770Sstevel@tonic-gate 	"/usr/man/mann",
780Sstevel@tonic-gate 	"/usr/man/mano",
790Sstevel@tonic-gate 	0
800Sstevel@tonic-gate };
810Sstevel@tonic-gate static char *srcdirs[]  = {
820Sstevel@tonic-gate 	"/usr/src/cmd",
830Sstevel@tonic-gate 	"/usr/src/head",
840Sstevel@tonic-gate 	"/usr/src/lib",
850Sstevel@tonic-gate 	"/usr/src/lib/libc",
860Sstevel@tonic-gate 	"/usr/src/lib/libc/port",
870Sstevel@tonic-gate 	"/usr/src/lib/libc/port/gen",
880Sstevel@tonic-gate 	"/usr/src/lib/libc/port/print",
890Sstevel@tonic-gate 	"/usr/src/lib/libc/port/stdio",
900Sstevel@tonic-gate 	"/usr/src/lib/libc/port/sys",
910Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc",
920Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/gen",
930Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/sys",
940Sstevel@tonic-gate 	"/usr/src/ucbcmd",
950Sstevel@tonic-gate 	"/usr/src/ucblib",
960Sstevel@tonic-gate 	"/usr/src/ucbinclude",
970Sstevel@tonic-gate 	"/usr/src/uts",
980Sstevel@tonic-gate 	"/usr/src/uts/common",
990Sstevel@tonic-gate 	"/usr/src/uts/sun",
1000Sstevel@tonic-gate 	"/usr/src/uts/sun4",
1010Sstevel@tonic-gate 	"/usr/src/uts/sun4c",
1020Sstevel@tonic-gate 	"/usr/src/uts/sparc",
1030Sstevel@tonic-gate 	"/usr/src/local",
1040Sstevel@tonic-gate 	"/usr/src/new",
1050Sstevel@tonic-gate 	"/usr/src/old",
1060Sstevel@tonic-gate 	0
1070Sstevel@tonic-gate };
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate char	sflag = 1;
1100Sstevel@tonic-gate char	bflag = 1;
1110Sstevel@tonic-gate char	mflag = 1;
1120Sstevel@tonic-gate char	**Sflag;
1130Sstevel@tonic-gate int	Scnt;
1140Sstevel@tonic-gate char	**Bflag;
1150Sstevel@tonic-gate int	Bcnt;
1160Sstevel@tonic-gate char	**Mflag;
1170Sstevel@tonic-gate int	Mcnt;
1180Sstevel@tonic-gate char	uflag;
119*669Schin 
120*669Schin void getlist(int *, char ***, char ***, int *);
121*669Schin void zerof(void);
122*669Schin void lookup(char *);
123*669Schin void looksrc(char *);
124*669Schin void lookbin(char *);
125*669Schin void lookman(char *);
126*669Schin void findv(char **, int, char *);
127*669Schin void find(char **, char *);
128*669Schin void findin(char *, char *);
129*669Schin 
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate  * whereis name
1320Sstevel@tonic-gate  * look for source, documentation and binaries
1330Sstevel@tonic-gate  */
134*669Schin int
main(int argc,char * argv[])135*669Schin main(int argc, char *argv[])
1360Sstevel@tonic-gate {
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	argc--, argv++;
1390Sstevel@tonic-gate 	if (argc == 0) {
1400Sstevel@tonic-gate usage:
141*669Schin 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] "
142*669Schin 		    "name...\n");
1430Sstevel@tonic-gate 		exit(1);
1440Sstevel@tonic-gate 	}
1450Sstevel@tonic-gate 	do
1460Sstevel@tonic-gate 		if (argv[0][0] == '-') {
147*669Schin 			char *cp = argv[0] + 1;
148*669Schin 			while (*cp) {
149*669Schin 
150*669Schin 				switch (*cp++) {
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 			case 'f':
1530Sstevel@tonic-gate 				break;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 			case 'S':
1560Sstevel@tonic-gate 				getlist(&argc, &argv, &Sflag, &Scnt);
1570Sstevel@tonic-gate 				break;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 			case 'B':
1600Sstevel@tonic-gate 				getlist(&argc, &argv, &Bflag, &Bcnt);
1610Sstevel@tonic-gate 				break;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 			case 'M':
1640Sstevel@tonic-gate 				getlist(&argc, &argv, &Mflag, &Mcnt);
1650Sstevel@tonic-gate 				break;
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 			case 's':
1680Sstevel@tonic-gate 				zerof();
1690Sstevel@tonic-gate 				sflag++;
1700Sstevel@tonic-gate 				continue;
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 			case 'u':
1730Sstevel@tonic-gate 				uflag++;
1740Sstevel@tonic-gate 				continue;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 			case 'b':
1770Sstevel@tonic-gate 				zerof();
1780Sstevel@tonic-gate 				bflag++;
1790Sstevel@tonic-gate 				continue;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 			case 'm':
1820Sstevel@tonic-gate 				zerof();
1830Sstevel@tonic-gate 				mflag++;
1840Sstevel@tonic-gate 				continue;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 			default:
1870Sstevel@tonic-gate 				goto usage;
188*669Schin 				}
1890Sstevel@tonic-gate 			}
1900Sstevel@tonic-gate 			argv++;
1910Sstevel@tonic-gate 		} else
1920Sstevel@tonic-gate 			lookup(*argv++);
1930Sstevel@tonic-gate 	while (--argc > 0);
194*669Schin 	return (0);
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate 
197*669Schin void
getlist(int * argcp,char *** argvp,char *** flagp,int * cntp)198*669Schin getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
1990Sstevel@tonic-gate {
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	(*argvp)++;
2020Sstevel@tonic-gate 	*flagp = *argvp;
2030Sstevel@tonic-gate 	*cntp = 0;
2040Sstevel@tonic-gate 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
2050Sstevel@tonic-gate 		(*cntp)++, (*argvp)++;
2060Sstevel@tonic-gate 	(*argcp)++;
2070Sstevel@tonic-gate 	(*argvp)--;
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate 
210*669Schin void
zerof(void)211*669Schin zerof(void)
2120Sstevel@tonic-gate {
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	if (sflag && bflag && mflag)
2150Sstevel@tonic-gate 		sflag = bflag = mflag = 0;
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate int	count;
2180Sstevel@tonic-gate int	print;
2190Sstevel@tonic-gate 
220*669Schin void
lookup(char * cp)221*669Schin lookup(char *cp)
2220Sstevel@tonic-gate {
223*669Schin 	char *dp;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
2260Sstevel@tonic-gate 		continue;
2270Sstevel@tonic-gate 	for (; dp > cp; dp--) {
2280Sstevel@tonic-gate 		if (*dp == '.') {
2290Sstevel@tonic-gate 			*dp = 0;
2300Sstevel@tonic-gate 			break;
2310Sstevel@tonic-gate 		}
2320Sstevel@tonic-gate 	}
2330Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
2340Sstevel@tonic-gate 		if (*dp == '/')
2350Sstevel@tonic-gate 			cp = dp + 1;
2360Sstevel@tonic-gate 	if (uflag) {
2370Sstevel@tonic-gate 		print = 0;
2380Sstevel@tonic-gate 		count = 0;
2390Sstevel@tonic-gate 	} else
2400Sstevel@tonic-gate 		print = 1;
2410Sstevel@tonic-gate again:
2420Sstevel@tonic-gate 	if (print)
2430Sstevel@tonic-gate 		printf("%s:", cp);
2440Sstevel@tonic-gate 	if (sflag) {
2450Sstevel@tonic-gate 		looksrc(cp);
2460Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2470Sstevel@tonic-gate 			print = 1;
2480Sstevel@tonic-gate 			goto again;
2490Sstevel@tonic-gate 		}
2500Sstevel@tonic-gate 	}
2510Sstevel@tonic-gate 	count = 0;
2520Sstevel@tonic-gate 	if (bflag) {
2530Sstevel@tonic-gate 		lookbin(cp);
2540Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2550Sstevel@tonic-gate 			print = 1;
2560Sstevel@tonic-gate 			goto again;
2570Sstevel@tonic-gate 		}
2580Sstevel@tonic-gate 	}
2590Sstevel@tonic-gate 	count = 0;
2600Sstevel@tonic-gate 	if (mflag) {
2610Sstevel@tonic-gate 		lookman(cp);
2620Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2630Sstevel@tonic-gate 			print = 1;
2640Sstevel@tonic-gate 			goto again;
2650Sstevel@tonic-gate 		}
2660Sstevel@tonic-gate 	}
2670Sstevel@tonic-gate 	if (print)
2680Sstevel@tonic-gate 		printf("\n");
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate 
271*669Schin void
looksrc(char * cp)272*669Schin looksrc(char *cp)
2730Sstevel@tonic-gate {
2740Sstevel@tonic-gate 	if (Sflag == 0) {
2750Sstevel@tonic-gate 		find(srcdirs, cp);
2760Sstevel@tonic-gate 	} else
2770Sstevel@tonic-gate 		findv(Sflag, Scnt, cp);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate 
280*669Schin void
lookbin(char * cp)281*669Schin lookbin(char *cp)
2820Sstevel@tonic-gate {
2830Sstevel@tonic-gate 	if (Bflag == 0)
2840Sstevel@tonic-gate 		find(bindirs, cp);
2850Sstevel@tonic-gate 	else
2860Sstevel@tonic-gate 		findv(Bflag, Bcnt, cp);
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate 
289*669Schin void
lookman(char * cp)290*669Schin lookman(char *cp)
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate 	if (Mflag == 0) {
2930Sstevel@tonic-gate 		find(mandirs, cp);
2940Sstevel@tonic-gate 	} else
2950Sstevel@tonic-gate 		findv(Mflag, Mcnt, cp);
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate 
298*669Schin void
findv(char ** dirv,int dirc,char * cp)299*669Schin findv(char **dirv, int dirc, char *cp)
3000Sstevel@tonic-gate {
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	while (dirc > 0)
3030Sstevel@tonic-gate 		findin(*dirv++, cp), dirc--;
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate 
306*669Schin void
find(char ** dirs,char * cp)307*669Schin find(char **dirs, char *cp)
3080Sstevel@tonic-gate {
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	while (*dirs)
3110Sstevel@tonic-gate 		findin(*dirs++, cp);
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate 
314*669Schin void
findin(char * dir,char * cp)315*669Schin findin(char *dir, char *cp)
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate 	DIR *dirp;
3180Sstevel@tonic-gate 	struct dirent *dp;
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	dirp = opendir(dir);
3210Sstevel@tonic-gate 	if (dirp == NULL)
3220Sstevel@tonic-gate 		return;
3230Sstevel@tonic-gate 	while ((dp = readdir(dirp)) != NULL) {
3240Sstevel@tonic-gate 		if (itsit(cp, dp->d_name)) {
3250Sstevel@tonic-gate 			count++;
3260Sstevel@tonic-gate 			if (print)
3270Sstevel@tonic-gate 				printf(" %s/%s", dir, dp->d_name);
3280Sstevel@tonic-gate 		}
3290Sstevel@tonic-gate 	}
3300Sstevel@tonic-gate 	closedir(dirp);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
333*669Schin int
itsit(char * cp,char * dp)334*669Schin itsit(char *cp, char *dp)
3350Sstevel@tonic-gate {
336*669Schin 	int i = strlen(dp);
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
3390Sstevel@tonic-gate 		return (1);
3400Sstevel@tonic-gate 	while (*cp && *dp && *cp == *dp)
3410Sstevel@tonic-gate 		cp++, dp++, i--;
3420Sstevel@tonic-gate 	if (*cp == 0 && *dp == 0)
3430Sstevel@tonic-gate 		return (1);
3440Sstevel@tonic-gate 	while (isdigit(*dp))
3450Sstevel@tonic-gate 		dp++;
3460Sstevel@tonic-gate 	if (*cp == 0 && *dp++ == '.') {
3470Sstevel@tonic-gate 		--i;
3480Sstevel@tonic-gate 		while (i > 0 && *dp)
3490Sstevel@tonic-gate 			if (--i, *dp++ == '.')
3500Sstevel@tonic-gate 				return (*dp++ == 'C' && *dp++ == 0);
3510Sstevel@tonic-gate 		return (1);
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 	return (0);
3540Sstevel@tonic-gate }
355