xref: /csrg-svn/old/whereis/whereis.c (revision 32752)
121590Sdist /*
221590Sdist  * Copyright (c) 1980 Regents of the University of California.
321590Sdist  * All rights reserved.  The Berkeley software License Agreement
421590Sdist  * specifies the terms and conditions for redistribution.
521590Sdist  */
621590Sdist 
713623Ssam #ifndef lint
821590Sdist char copyright[] =
921590Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1021590Sdist  All rights reserved.\n";
11*32752Sbostic #endif /* not lint */
126206Sroot 
1321590Sdist #ifndef lint
14*32752Sbostic static char sccsid[] = "@(#)whereis.c	5.2 (Berkeley) 12/03/87";
15*32752Sbostic #endif /* not lint */
1621590Sdist 
176732Smckusick #include <sys/param.h>
1813623Ssam #include <sys/dir.h>
191163Sbill #include <stdio.h>
201163Sbill #include <ctype.h>
211163Sbill 
221163Sbill static char *bindirs[] = {
231163Sbill 	"/etc",
241163Sbill 	"/bin",
251163Sbill 	"/usr/bin",
261163Sbill 	"/usr/games",
272371Skre 	"/lib",
282371Skre 	"/usr/ucb",
292371Skre 	"/usr/lib",
302371Skre 	"/usr/local",
312371Skre 	"/usr/new",
322371Skre 	"/usr/old",
336732Smckusick 	"/usr/hosts",
3412201Ssam 	"/usr/include",
351163Sbill 	0
361163Sbill };
371163Sbill static char *mandirs[] = {
381163Sbill 	"/usr/man/man1",
391163Sbill 	"/usr/man/man2",
401163Sbill 	"/usr/man/man3",
411163Sbill 	"/usr/man/man4",
421163Sbill 	"/usr/man/man5",
431163Sbill 	"/usr/man/man6",
441163Sbill 	"/usr/man/man7",
451163Sbill 	"/usr/man/man8",
4616077Sralph 	"/usr/man/manl",
4716077Sralph 	"/usr/man/mann",
4816077Sralph 	"/usr/man/mano",
491163Sbill 	0
501163Sbill };
511163Sbill static char *srcdirs[]  = {
526732Smckusick 	"/usr/src/bin",
536732Smckusick 	"/usr/src/usr.bin",
5410723Smckusick 	"/usr/src/etc",
5510723Smckusick 	"/usr/src/ucb",
561163Sbill 	"/usr/src/games",
5710723Smckusick 	"/usr/src/usr.lib",
586732Smckusick 	"/usr/src/lib",
5910723Smckusick 	"/usr/src/local",
6010723Smckusick 	"/usr/src/new",
6110723Smckusick 	"/usr/src/old",
6212201Ssam 	"/usr/src/include",
636732Smckusick 	"/usr/src/lib/libc/gen",
646732Smckusick 	"/usr/src/lib/libc/stdio",
656732Smckusick 	"/usr/src/lib/libc/sys",
6610723Smckusick 	"/usr/src/lib/libc/net/common",
6710723Smckusick 	"/usr/src/lib/libc/net/inet",
6810723Smckusick 	"/usr/src/lib/libc/net/misc",
6910723Smckusick 	"/usr/src/ucb/pascal",
7010723Smckusick 	"/usr/src/ucb/pascal/utilities",
712371Skre 	"/usr/src/undoc",
721163Sbill 	0
731163Sbill };
741163Sbill 
751163Sbill char	sflag = 1;
761163Sbill char	bflag = 1;
771163Sbill char	mflag = 1;
781163Sbill char	**Sflag;
791163Sbill int	Scnt;
801163Sbill char	**Bflag;
811163Sbill int	Bcnt;
821163Sbill char	**Mflag;
831163Sbill int	Mcnt;
841163Sbill char	uflag;
851163Sbill /*
861163Sbill  * whereis name
871163Sbill  * look for source, documentation and binaries
881163Sbill  */
891163Sbill main(argc, argv)
901163Sbill 	int argc;
911163Sbill 	char *argv[];
921163Sbill {
931163Sbill 
941163Sbill 	argc--, argv++;
951163Sbill 	if (argc == 0) {
961163Sbill usage:
971163Sbill 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
981163Sbill 		exit(1);
991163Sbill 	}
1001163Sbill 	do
1011163Sbill 		if (argv[0][0] == '-') {
1021163Sbill 			register char *cp = argv[0] + 1;
1031163Sbill 			while (*cp) switch (*cp++) {
1041163Sbill 
1051163Sbill 			case 'f':
1061163Sbill 				break;
1071163Sbill 
1081163Sbill 			case 'S':
1091163Sbill 				getlist(&argc, &argv, &Sflag, &Scnt);
1101163Sbill 				break;
1111163Sbill 
1121163Sbill 			case 'B':
1131163Sbill 				getlist(&argc, &argv, &Bflag, &Bcnt);
1141163Sbill 				break;
1151163Sbill 
1161163Sbill 			case 'M':
1171163Sbill 				getlist(&argc, &argv, &Mflag, &Mcnt);
1181163Sbill 				break;
1191163Sbill 
1201163Sbill 			case 's':
1211163Sbill 				zerof();
1221163Sbill 				sflag++;
1231163Sbill 				continue;
1241163Sbill 
1251163Sbill 			case 'u':
1261163Sbill 				uflag++;
1271163Sbill 				continue;
1281163Sbill 
1291163Sbill 			case 'b':
1301163Sbill 				zerof();
1311163Sbill 				bflag++;
1321163Sbill 				continue;
1331163Sbill 
1341163Sbill 			case 'm':
1351163Sbill 				zerof();
1361163Sbill 				mflag++;
1371163Sbill 				continue;
1381163Sbill 
1391163Sbill 			default:
1401163Sbill 				goto usage;
1411163Sbill 			}
1421163Sbill 			argv++;
1431163Sbill 		} else
1441163Sbill 			lookup(*argv++);
1451163Sbill 	while (--argc > 0);
146*32752Sbostic 	exit(0);
1471163Sbill }
1481163Sbill 
1491163Sbill getlist(argcp, argvp, flagp, cntp)
1501163Sbill 	char ***argvp;
1511163Sbill 	int *argcp;
1521163Sbill 	char ***flagp;
1531163Sbill 	int *cntp;
1541163Sbill {
1551163Sbill 
1561163Sbill 	(*argvp)++;
1571163Sbill 	*flagp = *argvp;
1581163Sbill 	*cntp = 0;
1591163Sbill 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
1601163Sbill 		(*cntp)++, (*argvp)++;
1611163Sbill 	(*argcp)++;
1621163Sbill 	(*argvp)--;
1631163Sbill }
1641163Sbill 
1651163Sbill 
1661163Sbill zerof()
1671163Sbill {
1681163Sbill 
1691163Sbill 	if (sflag && bflag && mflag)
1701163Sbill 		sflag = bflag = mflag = 0;
1711163Sbill }
1721163Sbill int	count;
1731163Sbill int	print;
1741163Sbill 
1751163Sbill 
1761163Sbill lookup(cp)
1771163Sbill 	register char *cp;
1781163Sbill {
1791163Sbill 	register char *dp;
1801163Sbill 
1811163Sbill 	for (dp = cp; *dp; dp++)
1821163Sbill 		continue;
1831163Sbill 	for (; dp > cp; dp--) {
1841163Sbill 		if (*dp == '.') {
1851163Sbill 			*dp = 0;
1861163Sbill 			break;
1871163Sbill 		}
1881163Sbill 	}
1891163Sbill 	for (dp = cp; *dp; dp++)
1901163Sbill 		if (*dp == '/')
1911163Sbill 			cp = dp + 1;
1921163Sbill 	if (uflag) {
1931163Sbill 		print = 0;
1941163Sbill 		count = 0;
1951163Sbill 	} else
1961163Sbill 		print = 1;
1971163Sbill again:
1981163Sbill 	if (print)
1991163Sbill 		printf("%s:", cp);
2001163Sbill 	if (sflag) {
2011163Sbill 		looksrc(cp);
2021163Sbill 		if (uflag && print == 0 && count != 1) {
2031163Sbill 			print = 1;
2041163Sbill 			goto again;
2051163Sbill 		}
2061163Sbill 	}
2071163Sbill 	count = 0;
2081163Sbill 	if (bflag) {
2091163Sbill 		lookbin(cp);
2101163Sbill 		if (uflag && print == 0 && count != 1) {
2111163Sbill 			print = 1;
2121163Sbill 			goto again;
2131163Sbill 		}
2141163Sbill 	}
2151163Sbill 	count = 0;
2161163Sbill 	if (mflag) {
2171163Sbill 		lookman(cp);
2181163Sbill 		if (uflag && print == 0 && count != 1) {
2191163Sbill 			print = 1;
2201163Sbill 			goto again;
2211163Sbill 		}
2221163Sbill 	}
2231163Sbill 	if (print)
2241163Sbill 		printf("\n");
2251163Sbill }
2261163Sbill 
2271163Sbill looksrc(cp)
2281163Sbill 	char *cp;
2291163Sbill {
2301163Sbill 	if (Sflag == 0) {
2311163Sbill 		find(srcdirs, cp);
2321163Sbill 	} else
2331163Sbill 		findv(Sflag, Scnt, cp);
2341163Sbill }
2351163Sbill 
2361163Sbill lookbin(cp)
2371163Sbill 	char *cp;
2381163Sbill {
2391163Sbill 	if (Bflag == 0)
2401163Sbill 		find(bindirs, cp);
2411163Sbill 	else
2421163Sbill 		findv(Bflag, Bcnt, cp);
2431163Sbill }
2441163Sbill 
2451163Sbill lookman(cp)
2461163Sbill 	char *cp;
2471163Sbill {
2481163Sbill 	if (Mflag == 0) {
2491163Sbill 		find(mandirs, cp);
2501163Sbill 	} else
2511163Sbill 		findv(Mflag, Mcnt, cp);
2521163Sbill }
2531163Sbill 
2541163Sbill findv(dirv, dirc, cp)
2551163Sbill 	char **dirv;
2561163Sbill 	int dirc;
2571163Sbill 	char *cp;
2581163Sbill {
2591163Sbill 
2601163Sbill 	while (dirc > 0)
2611163Sbill 		findin(*dirv++, cp), dirc--;
2621163Sbill }
2631163Sbill 
2641163Sbill find(dirs, cp)
2651163Sbill 	char **dirs;
2661163Sbill 	char *cp;
2671163Sbill {
2681163Sbill 
2691163Sbill 	while (*dirs)
2701163Sbill 		findin(*dirs++, cp);
2711163Sbill }
2721163Sbill 
2731163Sbill findin(dir, cp)
2741163Sbill 	char *dir, *cp;
2751163Sbill {
2766732Smckusick 	DIR *dirp;
2776732Smckusick 	struct direct *dp;
2781163Sbill 
2796732Smckusick 	dirp = opendir(dir);
2806732Smckusick 	if (dirp == NULL)
2811163Sbill 		return;
2826732Smckusick 	while ((dp = readdir(dirp)) != NULL) {
2836732Smckusick 		if (itsit(cp, dp->d_name)) {
2841163Sbill 			count++;
2851163Sbill 			if (print)
28610723Smckusick 				printf(" %s/%s", dir, dp->d_name);
2871163Sbill 		}
2881163Sbill 	}
2896732Smckusick 	closedir(dirp);
2901163Sbill }
2911163Sbill 
2921163Sbill itsit(cp, dp)
2931163Sbill 	register char *cp, *dp;
2941163Sbill {
29510723Smckusick 	register int i = strlen(dp);
2961163Sbill 
2971163Sbill 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
2981163Sbill 		return (1);
2991163Sbill 	while (*cp && *dp && *cp == *dp)
3001163Sbill 		cp++, dp++, i--;
3011163Sbill 	if (*cp == 0 && *dp == 0)
3021163Sbill 		return (1);
3031163Sbill 	while (isdigit(*dp))
3041163Sbill 		dp++;
3051163Sbill 	if (*cp == 0 && *dp++ == '.') {
3061163Sbill 		--i;
3071163Sbill 		while (i > 0 && *dp)
3081163Sbill 			if (--i, *dp++ == '.')
3091163Sbill 				return (*dp++ == 'C' && *dp++ == 0);
3101163Sbill 		return (1);
3111163Sbill 	}
3121163Sbill 	return (0);
3131163Sbill }
314