xref: /illumos-gate/usr/src/ucbcmd/whereis/whereis.c (revision 8c0b080c)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
87c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate 
127c478bd9Sstevel@tonic-gate #include <sys/param.h>
137c478bd9Sstevel@tonic-gate #include <dirent.h>
147c478bd9Sstevel@tonic-gate #include <stdio.h>
157c478bd9Sstevel@tonic-gate #include <ctype.h>
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate static char *bindirs[] = {
187c478bd9Sstevel@tonic-gate 	"/etc",
197c478bd9Sstevel@tonic-gate 	"/sbin",
207c478bd9Sstevel@tonic-gate 	"/usr/bin",
217c478bd9Sstevel@tonic-gate 	"/usr/ccs/bin",
227c478bd9Sstevel@tonic-gate 	"/usr/ccs/lib",
237c478bd9Sstevel@tonic-gate 	"/usr/lang",
247c478bd9Sstevel@tonic-gate 	"/usr/lbin",
257c478bd9Sstevel@tonic-gate 	"/usr/lib",
267c478bd9Sstevel@tonic-gate 	"/usr/sbin",
277c478bd9Sstevel@tonic-gate 	"/usr/ucb",
287c478bd9Sstevel@tonic-gate 	"/usr/ucblib",
297c478bd9Sstevel@tonic-gate 	"/usr/ucbinclude",
307c478bd9Sstevel@tonic-gate 	"/usr/games",
317c478bd9Sstevel@tonic-gate 	"/usr/local",
327c478bd9Sstevel@tonic-gate 	"/usr/local/bin",
337c478bd9Sstevel@tonic-gate 	"/usr/new",
347c478bd9Sstevel@tonic-gate 	"/usr/old",
357c478bd9Sstevel@tonic-gate 	"/usr/hosts",
367c478bd9Sstevel@tonic-gate 	"/usr/include",
377c478bd9Sstevel@tonic-gate 	"/usr/etc",
387c478bd9Sstevel@tonic-gate 	0
397c478bd9Sstevel@tonic-gate };
407c478bd9Sstevel@tonic-gate static char *mandirs[] = {
417c478bd9Sstevel@tonic-gate 	"/usr/man/man1",
427c478bd9Sstevel@tonic-gate 	"/usr/man/man1b",
437c478bd9Sstevel@tonic-gate 	"/usr/man/man1c",
447c478bd9Sstevel@tonic-gate 	"/usr/man/man1f",
457c478bd9Sstevel@tonic-gate 	"/usr/man/man1m",
467c478bd9Sstevel@tonic-gate 	"/usr/man/man1s",
477c478bd9Sstevel@tonic-gate 	"/usr/man/man2",
487c478bd9Sstevel@tonic-gate 	"/usr/man/man3",
497c478bd9Sstevel@tonic-gate 	"/usr/man/man3b",
507c478bd9Sstevel@tonic-gate 	"/usr/man/man3c",
517c478bd9Sstevel@tonic-gate 	"/usr/man/man3e",
527c478bd9Sstevel@tonic-gate 	"/usr/man/man3g",
537c478bd9Sstevel@tonic-gate 	"/usr/man/man3j",
547c478bd9Sstevel@tonic-gate 	"/usr/man/man3k",
557c478bd9Sstevel@tonic-gate 	"/usr/man/man3l",
567c478bd9Sstevel@tonic-gate 	"/usr/man/man3m",
577c478bd9Sstevel@tonic-gate 	"/usr/man/man3n",
587c478bd9Sstevel@tonic-gate 	"/usr/man/man3s",
597c478bd9Sstevel@tonic-gate 	"/usr/man/man3w",
607c478bd9Sstevel@tonic-gate 	"/usr/man/man3x",
617c478bd9Sstevel@tonic-gate 	"/usr/man/man3x11",
627c478bd9Sstevel@tonic-gate 	"/usr/man/man3xt",
637c478bd9Sstevel@tonic-gate 	"/usr/man/man4",
647c478bd9Sstevel@tonic-gate 	"/usr/man/man4b",
657c478bd9Sstevel@tonic-gate 	"/usr/man/man5",
667c478bd9Sstevel@tonic-gate 	"/usr/man/man6",
677c478bd9Sstevel@tonic-gate 	"/usr/man/man7",
687c478bd9Sstevel@tonic-gate 	"/usr/man/man7b",
697c478bd9Sstevel@tonic-gate 	"/usr/man/man8",
707c478bd9Sstevel@tonic-gate 	"/usr/man/man9e",
717c478bd9Sstevel@tonic-gate 	"/usr/man/man9f",
727c478bd9Sstevel@tonic-gate 	"/usr/man/man9s",
737c478bd9Sstevel@tonic-gate 	"/usr/man/manl",
747c478bd9Sstevel@tonic-gate 	"/usr/man/mann",
757c478bd9Sstevel@tonic-gate 	"/usr/man/mano",
767c478bd9Sstevel@tonic-gate 	0
777c478bd9Sstevel@tonic-gate };
787c478bd9Sstevel@tonic-gate static char *srcdirs[]  = {
797c478bd9Sstevel@tonic-gate 	"/usr/src/cmd",
807c478bd9Sstevel@tonic-gate 	"/usr/src/head",
817c478bd9Sstevel@tonic-gate 	"/usr/src/lib",
827c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc",
837c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/port",
847c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/port/gen",
857c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/port/print",
867c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/port/stdio",
877c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/port/sys",
887c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc",
897c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/gen",
907c478bd9Sstevel@tonic-gate 	"/usr/src/lib/libc/sparc/sys",
917c478bd9Sstevel@tonic-gate 	"/usr/src/ucbcmd",
927c478bd9Sstevel@tonic-gate 	"/usr/src/ucblib",
937c478bd9Sstevel@tonic-gate 	"/usr/src/ucbinclude",
947c478bd9Sstevel@tonic-gate 	"/usr/src/uts",
957c478bd9Sstevel@tonic-gate 	"/usr/src/uts/common",
967c478bd9Sstevel@tonic-gate 	"/usr/src/uts/sun",
977c478bd9Sstevel@tonic-gate 	"/usr/src/uts/sun4",
987c478bd9Sstevel@tonic-gate 	"/usr/src/uts/sun4c",
997c478bd9Sstevel@tonic-gate 	"/usr/src/uts/sparc",
1007c478bd9Sstevel@tonic-gate 	"/usr/src/local",
1017c478bd9Sstevel@tonic-gate 	"/usr/src/new",
1027c478bd9Sstevel@tonic-gate 	"/usr/src/old",
1037c478bd9Sstevel@tonic-gate 	0
1047c478bd9Sstevel@tonic-gate };
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate char	sflag = 1;
1077c478bd9Sstevel@tonic-gate char	bflag = 1;
1087c478bd9Sstevel@tonic-gate char	mflag = 1;
1097c478bd9Sstevel@tonic-gate char	**Sflag;
1107c478bd9Sstevel@tonic-gate int	Scnt;
1117c478bd9Sstevel@tonic-gate char	**Bflag;
1127c478bd9Sstevel@tonic-gate int	Bcnt;
1137c478bd9Sstevel@tonic-gate char	**Mflag;
1147c478bd9Sstevel@tonic-gate int	Mcnt;
1157c478bd9Sstevel@tonic-gate char	uflag;
116*cc6c5292Schin 
117*cc6c5292Schin void getlist(int *, char ***, char ***, int *);
118*cc6c5292Schin void zerof(void);
119*cc6c5292Schin void lookup(char *);
120*cc6c5292Schin void looksrc(char *);
121*cc6c5292Schin void lookbin(char *);
122*cc6c5292Schin void lookman(char *);
123*cc6c5292Schin void findv(char **, int, char *);
124*cc6c5292Schin void find(char **, char *);
125*cc6c5292Schin void findin(char *, char *);
126*cc6c5292Schin 
1277c478bd9Sstevel@tonic-gate /*
1287c478bd9Sstevel@tonic-gate  * whereis name
1297c478bd9Sstevel@tonic-gate  * look for source, documentation and binaries
1307c478bd9Sstevel@tonic-gate  */
131*cc6c5292Schin int
main(int argc,char * argv[])132*cc6c5292Schin main(int argc, char *argv[])
1337c478bd9Sstevel@tonic-gate {
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	argc--, argv++;
1367c478bd9Sstevel@tonic-gate 	if (argc == 0) {
1377c478bd9Sstevel@tonic-gate usage:
138*cc6c5292Schin 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] "
139*cc6c5292Schin 		    "name...\n");
1407c478bd9Sstevel@tonic-gate 		exit(1);
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 	do
1437c478bd9Sstevel@tonic-gate 		if (argv[0][0] == '-') {
144*cc6c5292Schin 			char *cp = argv[0] + 1;
145*cc6c5292Schin 			while (*cp) {
146*cc6c5292Schin 
147*cc6c5292Schin 				switch (*cp++) {
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 			case 'f':
1507c478bd9Sstevel@tonic-gate 				break;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 			case 'S':
1537c478bd9Sstevel@tonic-gate 				getlist(&argc, &argv, &Sflag, &Scnt);
1547c478bd9Sstevel@tonic-gate 				break;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 			case 'B':
1577c478bd9Sstevel@tonic-gate 				getlist(&argc, &argv, &Bflag, &Bcnt);
1587c478bd9Sstevel@tonic-gate 				break;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 			case 'M':
1617c478bd9Sstevel@tonic-gate 				getlist(&argc, &argv, &Mflag, &Mcnt);
1627c478bd9Sstevel@tonic-gate 				break;
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 			case 's':
1657c478bd9Sstevel@tonic-gate 				zerof();
1667c478bd9Sstevel@tonic-gate 				sflag++;
1677c478bd9Sstevel@tonic-gate 				continue;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 			case 'u':
1707c478bd9Sstevel@tonic-gate 				uflag++;
1717c478bd9Sstevel@tonic-gate 				continue;
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 			case 'b':
1747c478bd9Sstevel@tonic-gate 				zerof();
1757c478bd9Sstevel@tonic-gate 				bflag++;
1767c478bd9Sstevel@tonic-gate 				continue;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 			case 'm':
1797c478bd9Sstevel@tonic-gate 				zerof();
1807c478bd9Sstevel@tonic-gate 				mflag++;
1817c478bd9Sstevel@tonic-gate 				continue;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 			default:
1847c478bd9Sstevel@tonic-gate 				goto usage;
1857c478bd9Sstevel@tonic-gate 				}
186*cc6c5292Schin 			}
1877c478bd9Sstevel@tonic-gate 			argv++;
1887c478bd9Sstevel@tonic-gate 		} else
1897c478bd9Sstevel@tonic-gate 			lookup(*argv++);
1907c478bd9Sstevel@tonic-gate 	while (--argc > 0);
191*cc6c5292Schin 	return (0);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
194*cc6c5292Schin void
getlist(int * argcp,char *** argvp,char *** flagp,int * cntp)195*cc6c5292Schin getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	(*argvp)++;
1997c478bd9Sstevel@tonic-gate 	*flagp = *argvp;
2007c478bd9Sstevel@tonic-gate 	*cntp = 0;
2017c478bd9Sstevel@tonic-gate 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
2027c478bd9Sstevel@tonic-gate 		(*cntp)++, (*argvp)++;
2037c478bd9Sstevel@tonic-gate 	(*argcp)++;
2047c478bd9Sstevel@tonic-gate 	(*argvp)--;
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
207*cc6c5292Schin void
zerof(void)208*cc6c5292Schin zerof(void)
2097c478bd9Sstevel@tonic-gate {
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (sflag && bflag && mflag)
2127c478bd9Sstevel@tonic-gate 		sflag = bflag = mflag = 0;
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate int	count;
2157c478bd9Sstevel@tonic-gate int	print;
2167c478bd9Sstevel@tonic-gate 
217*cc6c5292Schin void
lookup(char * cp)218*cc6c5292Schin lookup(char *cp)
2197c478bd9Sstevel@tonic-gate {
220*cc6c5292Schin 	char *dp;
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
2237c478bd9Sstevel@tonic-gate 		continue;
2247c478bd9Sstevel@tonic-gate 	for (; dp > cp; dp--) {
2257c478bd9Sstevel@tonic-gate 		if (*dp == '.') {
2267c478bd9Sstevel@tonic-gate 			*dp = 0;
2277c478bd9Sstevel@tonic-gate 			break;
2287c478bd9Sstevel@tonic-gate 		}
2297c478bd9Sstevel@tonic-gate 	}
2307c478bd9Sstevel@tonic-gate 	for (dp = cp; *dp; dp++)
2317c478bd9Sstevel@tonic-gate 		if (*dp == '/')
2327c478bd9Sstevel@tonic-gate 			cp = dp + 1;
2337c478bd9Sstevel@tonic-gate 	if (uflag) {
2347c478bd9Sstevel@tonic-gate 		print = 0;
2357c478bd9Sstevel@tonic-gate 		count = 0;
2367c478bd9Sstevel@tonic-gate 	} else
2377c478bd9Sstevel@tonic-gate 		print = 1;
2387c478bd9Sstevel@tonic-gate again:
2397c478bd9Sstevel@tonic-gate 	if (print)
2407c478bd9Sstevel@tonic-gate 		printf("%s:", cp);
2417c478bd9Sstevel@tonic-gate 	if (sflag) {
2427c478bd9Sstevel@tonic-gate 		looksrc(cp);
2437c478bd9Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2447c478bd9Sstevel@tonic-gate 			print = 1;
2457c478bd9Sstevel@tonic-gate 			goto again;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 	}
2487c478bd9Sstevel@tonic-gate 	count = 0;
2497c478bd9Sstevel@tonic-gate 	if (bflag) {
2507c478bd9Sstevel@tonic-gate 		lookbin(cp);
2517c478bd9Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2527c478bd9Sstevel@tonic-gate 			print = 1;
2537c478bd9Sstevel@tonic-gate 			goto again;
2547c478bd9Sstevel@tonic-gate 		}
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 	count = 0;
2577c478bd9Sstevel@tonic-gate 	if (mflag) {
2587c478bd9Sstevel@tonic-gate 		lookman(cp);
2597c478bd9Sstevel@tonic-gate 		if (uflag && print == 0 && count != 1) {
2607c478bd9Sstevel@tonic-gate 			print = 1;
2617c478bd9Sstevel@tonic-gate 			goto again;
2627c478bd9Sstevel@tonic-gate 		}
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 	if (print)
2657c478bd9Sstevel@tonic-gate 		printf("\n");
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate 
268*cc6c5292Schin void
looksrc(char * cp)269*cc6c5292Schin looksrc(char *cp)
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate 	if (Sflag == 0) {
2727c478bd9Sstevel@tonic-gate 		find(srcdirs, cp);
2737c478bd9Sstevel@tonic-gate 	} else
2747c478bd9Sstevel@tonic-gate 		findv(Sflag, Scnt, cp);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate 
277*cc6c5292Schin void
lookbin(char * cp)278*cc6c5292Schin lookbin(char *cp)
2797c478bd9Sstevel@tonic-gate {
2807c478bd9Sstevel@tonic-gate 	if (Bflag == 0)
2817c478bd9Sstevel@tonic-gate 		find(bindirs, cp);
2827c478bd9Sstevel@tonic-gate 	else
2837c478bd9Sstevel@tonic-gate 		findv(Bflag, Bcnt, cp);
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate 
286*cc6c5292Schin void
lookman(char * cp)287*cc6c5292Schin lookman(char *cp)
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate 	if (Mflag == 0) {
2907c478bd9Sstevel@tonic-gate 		find(mandirs, cp);
2917c478bd9Sstevel@tonic-gate 	} else
2927c478bd9Sstevel@tonic-gate 		findv(Mflag, Mcnt, cp);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
295*cc6c5292Schin void
findv(char ** dirv,int dirc,char * cp)296*cc6c5292Schin findv(char **dirv, int dirc, char *cp)
2977c478bd9Sstevel@tonic-gate {
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	while (dirc > 0)
3007c478bd9Sstevel@tonic-gate 		findin(*dirv++, cp), dirc--;
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
303*cc6c5292Schin void
find(char ** dirs,char * cp)304*cc6c5292Schin find(char **dirs, char *cp)
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	while (*dirs)
3087c478bd9Sstevel@tonic-gate 		findin(*dirs++, cp);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate 
311*cc6c5292Schin void
findin(char * dir,char * cp)312*cc6c5292Schin findin(char *dir, char *cp)
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate 	DIR *dirp;
3157c478bd9Sstevel@tonic-gate 	struct dirent *dp;
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	dirp = opendir(dir);
3187c478bd9Sstevel@tonic-gate 	if (dirp == NULL)
3197c478bd9Sstevel@tonic-gate 		return;
3207c478bd9Sstevel@tonic-gate 	while ((dp = readdir(dirp)) != NULL) {
3217c478bd9Sstevel@tonic-gate 		if (itsit(cp, dp->d_name)) {
3227c478bd9Sstevel@tonic-gate 			count++;
3237c478bd9Sstevel@tonic-gate 			if (print)
3247c478bd9Sstevel@tonic-gate 				printf(" %s/%s", dir, dp->d_name);
3257c478bd9Sstevel@tonic-gate 		}
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 	closedir(dirp);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate 
330*cc6c5292Schin int
itsit(char * cp,char * dp)331*cc6c5292Schin itsit(char *cp, char *dp)
3327c478bd9Sstevel@tonic-gate {
333*cc6c5292Schin 	int i = strlen(dp);
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
3367c478bd9Sstevel@tonic-gate 		return (1);
3377c478bd9Sstevel@tonic-gate 	while (*cp && *dp && *cp == *dp)
3387c478bd9Sstevel@tonic-gate 		cp++, dp++, i--;
3397c478bd9Sstevel@tonic-gate 	if (*cp == 0 && *dp == 0)
3407c478bd9Sstevel@tonic-gate 		return (1);
3417c478bd9Sstevel@tonic-gate 	while (isdigit(*dp))
3427c478bd9Sstevel@tonic-gate 		dp++;
3437c478bd9Sstevel@tonic-gate 	if (*cp == 0 && *dp++ == '.') {
3447c478bd9Sstevel@tonic-gate 		--i;
3457c478bd9Sstevel@tonic-gate 		while (i > 0 && *dp)
3467c478bd9Sstevel@tonic-gate 			if (--i, *dp++ == '.')
3477c478bd9Sstevel@tonic-gate 				return (*dp++ == 'C' && *dp++ == 0);
3487c478bd9Sstevel@tonic-gate 		return (1);
3497c478bd9Sstevel@tonic-gate 	}
3507c478bd9Sstevel@tonic-gate 	return (0);
3517c478bd9Sstevel@tonic-gate }
352