xref: /csrg-svn/old/whereis/whereis.c (revision 44591)
121590Sdist /*
240378Sbostic  * Copyright (c) 1980, 1990 The Regents of the University of California.
340378Sbostic  * All rights reserved.
440378Sbostic  *
540378Sbostic  * Redistribution and use in source and binary forms are permitted
640378Sbostic  * provided that the above copyright notice and this paragraph are
740378Sbostic  * duplicated in all such forms and that any documentation,
840378Sbostic  * advertising materials, and other materials related to such
940378Sbostic  * distribution and use acknowledge that the software was developed
1040378Sbostic  * by the University of California, Berkeley.  The name of the
1140378Sbostic  * University may not be used to endorse or promote products derived
1240378Sbostic  * from this software without specific prior written permission.
1340378Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1440378Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1540378Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621590Sdist  */
1721590Sdist 
1813623Ssam #ifndef lint
1921590Sdist char copyright[] =
2040378Sbostic "@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\
2121590Sdist  All rights reserved.\n";
2232752Sbostic #endif /* not lint */
236206Sroot 
2421590Sdist #ifndef lint
25*44591Smarc static char sccsid[] = "@(#)whereis.c	5.4 (Berkeley) 06/29/90";
2632752Sbostic #endif /* not lint */
2721590Sdist 
286732Smckusick #include <sys/param.h>
2913623Ssam #include <sys/dir.h>
301163Sbill #include <stdio.h>
311163Sbill #include <ctype.h>
321163Sbill 
331163Sbill static char *bindirs[] = {
34*44591Smarc 	"/bin",
35*44591Smarc 	"/sbin",
36*44591Smarc 	"/usr/ucb",
37*44591Smarc 	"/usr/bin",
38*44591Smarc 	"/usr/sbin",
39*44591Smarc 	"/usr/old",
40*44591Smarc 	"/usr/contrib",
41*44591Smarc 	"/usr/games",
42*44591Smarc 	"/usr/local",
43*44591Smarc 	"/usr/libexec",
44*44591Smarc 	"/usr/include",
45*44591Smarc 	"/usr/hosts",
46*44591Smarc 	"/usr/share", /*?*/
471163Sbill 	"/etc",
48*44591Smarc #ifdef notdef
49*44591Smarc 	/* before reorg */
50*44591Smarc 	"/etc",
511163Sbill 	"/bin",
521163Sbill 	"/usr/bin",
531163Sbill 	"/usr/games",
542371Skre 	"/lib",
552371Skre 	"/usr/ucb",
562371Skre 	"/usr/lib",
572371Skre 	"/usr/local",
582371Skre 	"/usr/new",
592371Skre 	"/usr/old",
606732Smckusick 	"/usr/hosts",
6112201Ssam 	"/usr/include",
62*44591Smarc #endif
631163Sbill 	0
641163Sbill };
65*44591Smarc /* This needs to be redone - man pages live with sources */
661163Sbill static char *mandirs[] = {
671163Sbill 	"/usr/man/man1",
681163Sbill 	"/usr/man/man2",
691163Sbill 	"/usr/man/man3",
701163Sbill 	"/usr/man/man4",
711163Sbill 	"/usr/man/man5",
721163Sbill 	"/usr/man/man6",
731163Sbill 	"/usr/man/man7",
741163Sbill 	"/usr/man/man8",
7516077Sralph 	"/usr/man/manl",
7616077Sralph 	"/usr/man/mann",
7716077Sralph 	"/usr/man/mano",
781163Sbill 	0
791163Sbill };
801163Sbill static char *srcdirs[]  = {
816732Smckusick 	"/usr/src/bin",
82*44591Smarc 	"/usr/src/sbin",
83*44591Smarc 	"/usr/src/etc",
84*44591Smarc 	"/usr/src/pgrm",
856732Smckusick 	"/usr/src/usr.bin",
86*44591Smarc 	"/usr/src/usr.sbin",
87*44591Smarc 	"/usr/src/usr.ucb",
88*44591Smarc 	"/usr/src/usr.new",
89*44591Smarc 	"/usr/src/usr.lib",
90*44591Smarc 	"/usr/src/libexec",
91*44591Smarc 	"/usr/src/libdata",
92*44591Smarc 	"/usr/src/share",
93*44591Smarc 	"/usr/src/contrib",
94*44591Smarc 	"/usr/src/athena",
95*44591Smarc 	"/usr/src/devel",
96*44591Smarc 	"/usr/src/games",
97*44591Smarc 	"/usr/src/local",
98*44591Smarc 	"/usr/src/man",
99*44591Smarc 	"/usr/src/root",
100*44591Smarc 	"/usr/src/old",
101*44591Smarc 	"/usr/src/include",
102*44591Smarc 	/* still need libs */
103*44591Smarc #ifdef notdef /* before reorg */
104*44591Smarc 	"/usr/src/bin",
105*44591Smarc 	"/usr/src/usr.bin",
10610723Smckusick 	"/usr/src/etc",
10710723Smckusick 	"/usr/src/ucb",
1081163Sbill 	"/usr/src/games",
10910723Smckusick 	"/usr/src/usr.lib",
1106732Smckusick 	"/usr/src/lib",
11110723Smckusick 	"/usr/src/local",
11210723Smckusick 	"/usr/src/new",
11310723Smckusick 	"/usr/src/old",
11412201Ssam 	"/usr/src/include",
1156732Smckusick 	"/usr/src/lib/libc/gen",
1166732Smckusick 	"/usr/src/lib/libc/stdio",
1176732Smckusick 	"/usr/src/lib/libc/sys",
11810723Smckusick 	"/usr/src/lib/libc/net/common",
11910723Smckusick 	"/usr/src/lib/libc/net/inet",
12010723Smckusick 	"/usr/src/lib/libc/net/misc",
12110723Smckusick 	"/usr/src/ucb/pascal",
12210723Smckusick 	"/usr/src/ucb/pascal/utilities",
1232371Skre 	"/usr/src/undoc",
124*44591Smarc #endif
1251163Sbill 	0
1261163Sbill };
1271163Sbill 
1281163Sbill char	sflag = 1;
1291163Sbill char	bflag = 1;
1301163Sbill char	mflag = 1;
1311163Sbill char	**Sflag;
1321163Sbill int	Scnt;
1331163Sbill char	**Bflag;
1341163Sbill int	Bcnt;
1351163Sbill char	**Mflag;
1361163Sbill int	Mcnt;
1371163Sbill char	uflag;
1381163Sbill /*
1391163Sbill  * whereis name
1401163Sbill  * look for source, documentation and binaries
1411163Sbill  */
1421163Sbill main(argc, argv)
1431163Sbill 	int argc;
1441163Sbill 	char *argv[];
1451163Sbill {
1461163Sbill 
1471163Sbill 	argc--, argv++;
1481163Sbill 	if (argc == 0) {
1491163Sbill usage:
1501163Sbill 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
1511163Sbill 		exit(1);
1521163Sbill 	}
1531163Sbill 	do
1541163Sbill 		if (argv[0][0] == '-') {
1551163Sbill 			register char *cp = argv[0] + 1;
1561163Sbill 			while (*cp) switch (*cp++) {
1571163Sbill 
1581163Sbill 			case 'f':
1591163Sbill 				break;
1601163Sbill 
1611163Sbill 			case 'S':
1621163Sbill 				getlist(&argc, &argv, &Sflag, &Scnt);
1631163Sbill 				break;
1641163Sbill 
1651163Sbill 			case 'B':
1661163Sbill 				getlist(&argc, &argv, &Bflag, &Bcnt);
1671163Sbill 				break;
1681163Sbill 
1691163Sbill 			case 'M':
1701163Sbill 				getlist(&argc, &argv, &Mflag, &Mcnt);
1711163Sbill 				break;
1721163Sbill 
1731163Sbill 			case 's':
1741163Sbill 				zerof();
1751163Sbill 				sflag++;
1761163Sbill 				continue;
1771163Sbill 
1781163Sbill 			case 'u':
1791163Sbill 				uflag++;
1801163Sbill 				continue;
1811163Sbill 
1821163Sbill 			case 'b':
1831163Sbill 				zerof();
1841163Sbill 				bflag++;
1851163Sbill 				continue;
1861163Sbill 
1871163Sbill 			case 'm':
1881163Sbill 				zerof();
1891163Sbill 				mflag++;
1901163Sbill 				continue;
1911163Sbill 
1921163Sbill 			default:
1931163Sbill 				goto usage;
1941163Sbill 			}
1951163Sbill 			argv++;
1961163Sbill 		} else
1971163Sbill 			lookup(*argv++);
1981163Sbill 	while (--argc > 0);
19932752Sbostic 	exit(0);
2001163Sbill }
2011163Sbill 
2021163Sbill getlist(argcp, argvp, flagp, cntp)
2031163Sbill 	char ***argvp;
2041163Sbill 	int *argcp;
2051163Sbill 	char ***flagp;
2061163Sbill 	int *cntp;
2071163Sbill {
2081163Sbill 
2091163Sbill 	(*argvp)++;
2101163Sbill 	*flagp = *argvp;
2111163Sbill 	*cntp = 0;
2121163Sbill 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
2131163Sbill 		(*cntp)++, (*argvp)++;
2141163Sbill 	(*argcp)++;
2151163Sbill 	(*argvp)--;
2161163Sbill }
2171163Sbill 
2181163Sbill 
2191163Sbill zerof()
2201163Sbill {
2211163Sbill 
2221163Sbill 	if (sflag && bflag && mflag)
2231163Sbill 		sflag = bflag = mflag = 0;
2241163Sbill }
2251163Sbill int	count;
2261163Sbill int	print;
2271163Sbill 
2281163Sbill 
2291163Sbill lookup(cp)
2301163Sbill 	register char *cp;
2311163Sbill {
2321163Sbill 	register char *dp;
2331163Sbill 
2341163Sbill 	for (dp = cp; *dp; dp++)
2351163Sbill 		continue;
2361163Sbill 	for (; dp > cp; dp--) {
2371163Sbill 		if (*dp == '.') {
2381163Sbill 			*dp = 0;
2391163Sbill 			break;
2401163Sbill 		}
2411163Sbill 	}
2421163Sbill 	for (dp = cp; *dp; dp++)
2431163Sbill 		if (*dp == '/')
2441163Sbill 			cp = dp + 1;
2451163Sbill 	if (uflag) {
2461163Sbill 		print = 0;
2471163Sbill 		count = 0;
2481163Sbill 	} else
2491163Sbill 		print = 1;
2501163Sbill again:
2511163Sbill 	if (print)
2521163Sbill 		printf("%s:", cp);
2531163Sbill 	if (sflag) {
2541163Sbill 		looksrc(cp);
2551163Sbill 		if (uflag && print == 0 && count != 1) {
2561163Sbill 			print = 1;
2571163Sbill 			goto again;
2581163Sbill 		}
2591163Sbill 	}
2601163Sbill 	count = 0;
2611163Sbill 	if (bflag) {
2621163Sbill 		lookbin(cp);
2631163Sbill 		if (uflag && print == 0 && count != 1) {
2641163Sbill 			print = 1;
2651163Sbill 			goto again;
2661163Sbill 		}
2671163Sbill 	}
2681163Sbill 	count = 0;
2691163Sbill 	if (mflag) {
2701163Sbill 		lookman(cp);
2711163Sbill 		if (uflag && print == 0 && count != 1) {
2721163Sbill 			print = 1;
2731163Sbill 			goto again;
2741163Sbill 		}
2751163Sbill 	}
2761163Sbill 	if (print)
2771163Sbill 		printf("\n");
2781163Sbill }
2791163Sbill 
2801163Sbill looksrc(cp)
2811163Sbill 	char *cp;
2821163Sbill {
2831163Sbill 	if (Sflag == 0) {
2841163Sbill 		find(srcdirs, cp);
2851163Sbill 	} else
2861163Sbill 		findv(Sflag, Scnt, cp);
2871163Sbill }
2881163Sbill 
2891163Sbill lookbin(cp)
2901163Sbill 	char *cp;
2911163Sbill {
2921163Sbill 	if (Bflag == 0)
2931163Sbill 		find(bindirs, cp);
2941163Sbill 	else
2951163Sbill 		findv(Bflag, Bcnt, cp);
2961163Sbill }
2971163Sbill 
2981163Sbill lookman(cp)
2991163Sbill 	char *cp;
3001163Sbill {
3011163Sbill 	if (Mflag == 0) {
3021163Sbill 		find(mandirs, cp);
3031163Sbill 	} else
3041163Sbill 		findv(Mflag, Mcnt, cp);
3051163Sbill }
3061163Sbill 
3071163Sbill findv(dirv, dirc, cp)
3081163Sbill 	char **dirv;
3091163Sbill 	int dirc;
3101163Sbill 	char *cp;
3111163Sbill {
3121163Sbill 
3131163Sbill 	while (dirc > 0)
3141163Sbill 		findin(*dirv++, cp), dirc--;
3151163Sbill }
3161163Sbill 
3171163Sbill find(dirs, cp)
3181163Sbill 	char **dirs;
3191163Sbill 	char *cp;
3201163Sbill {
3211163Sbill 
3221163Sbill 	while (*dirs)
3231163Sbill 		findin(*dirs++, cp);
3241163Sbill }
3251163Sbill 
3261163Sbill findin(dir, cp)
3271163Sbill 	char *dir, *cp;
3281163Sbill {
3296732Smckusick 	DIR *dirp;
3306732Smckusick 	struct direct *dp;
3311163Sbill 
3326732Smckusick 	dirp = opendir(dir);
3336732Smckusick 	if (dirp == NULL)
3341163Sbill 		return;
3356732Smckusick 	while ((dp = readdir(dirp)) != NULL) {
3366732Smckusick 		if (itsit(cp, dp->d_name)) {
3371163Sbill 			count++;
3381163Sbill 			if (print)
33910723Smckusick 				printf(" %s/%s", dir, dp->d_name);
3401163Sbill 		}
3411163Sbill 	}
3426732Smckusick 	closedir(dirp);
3431163Sbill }
3441163Sbill 
3451163Sbill itsit(cp, dp)
3461163Sbill 	register char *cp, *dp;
3471163Sbill {
34810723Smckusick 	register int i = strlen(dp);
3491163Sbill 
3501163Sbill 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
3511163Sbill 		return (1);
3521163Sbill 	while (*cp && *dp && *cp == *dp)
3531163Sbill 		cp++, dp++, i--;
3541163Sbill 	if (*cp == 0 && *dp == 0)
3551163Sbill 		return (1);
3561163Sbill 	while (isdigit(*dp))
3571163Sbill 		dp++;
3581163Sbill 	if (*cp == 0 && *dp++ == '.') {
3591163Sbill 		--i;
3601163Sbill 		while (i > 0 && *dp)
3611163Sbill 			if (--i, *dp++ == '.')
3621163Sbill 				return (*dp++ == 'C' && *dp++ == 0);
3631163Sbill 		return (1);
3641163Sbill 	}
3651163Sbill 	return (0);
3661163Sbill }
367