Home | History | Annotate | Line # | Download | only in whereis
whereis.c revision 1.1
      1 /*-
      2  * Copyright (c) 1980 The Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 char copyright[] =
     36 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
     37  All rights reserved.\n";
     38 #endif /* not lint */
     39 
     40 #ifndef lint
     41 static char sccsid[] = "@(#)whereis.c	5.5 (Berkeley) 4/18/91";
     42 #endif /* not lint */
     43 
     44 #include <sys/param.h>
     45 #include <sys/dir.h>
     46 #include <stdio.h>
     47 #include <ctype.h>
     48 
     49 static char *bindirs[] = {
     50 	"/bin",
     51 	"/sbin",
     52 	"/usr/ucb",
     53 	"/usr/bin",
     54 	"/usr/sbin",
     55 	"/usr/old",
     56 	"/usr/contrib",
     57 	"/usr/games",
     58 	"/usr/local",
     59 	"/usr/libexec",
     60 	"/usr/include",
     61 	"/usr/hosts",
     62 	"/usr/share", /*?*/
     63 	"/etc",
     64 #ifdef notdef
     65 	/* before reorg */
     66 	"/etc",
     67 	"/bin",
     68 	"/usr/bin",
     69 	"/usr/games",
     70 	"/lib",
     71 	"/usr/ucb",
     72 	"/usr/lib",
     73 	"/usr/local",
     74 	"/usr/new",
     75 	"/usr/old",
     76 	"/usr/hosts",
     77 	"/usr/include",
     78 #endif
     79 	0
     80 };
     81 /* This needs to be redone - man pages live with sources */
     82 static char *mandirs[] = {
     83 	"/usr/man/man1",
     84 	"/usr/man/man2",
     85 	"/usr/man/man3",
     86 	"/usr/man/man4",
     87 	"/usr/man/man5",
     88 	"/usr/man/man6",
     89 	"/usr/man/man7",
     90 	"/usr/man/man8",
     91 	"/usr/man/manl",
     92 	"/usr/man/mann",
     93 	"/usr/man/mano",
     94 	0
     95 };
     96 static char *srcdirs[]  = {
     97 	"/usr/src/bin",
     98 	"/usr/src/sbin",
     99 	"/usr/src/etc",
    100 	"/usr/src/pgrm",
    101 	"/usr/src/usr.bin",
    102 	"/usr/src/usr.sbin",
    103 	"/usr/src/usr.ucb",
    104 	"/usr/src/usr.new",
    105 	"/usr/src/usr.lib",
    106 	"/usr/src/libexec",
    107 	"/usr/src/libdata",
    108 	"/usr/src/share",
    109 	"/usr/src/contrib",
    110 	"/usr/src/athena",
    111 	"/usr/src/devel",
    112 	"/usr/src/games",
    113 	"/usr/src/local",
    114 	"/usr/src/man",
    115 	"/usr/src/root",
    116 	"/usr/src/old",
    117 	"/usr/src/include",
    118 	/* still need libs */
    119 #ifdef notdef /* before reorg */
    120 	"/usr/src/bin",
    121 	"/usr/src/usr.bin",
    122 	"/usr/src/etc",
    123 	"/usr/src/ucb",
    124 	"/usr/src/games",
    125 	"/usr/src/usr.lib",
    126 	"/usr/src/lib",
    127 	"/usr/src/local",
    128 	"/usr/src/new",
    129 	"/usr/src/old",
    130 	"/usr/src/include",
    131 	"/usr/src/lib/libc/gen",
    132 	"/usr/src/lib/libc/stdio",
    133 	"/usr/src/lib/libc/sys",
    134 	"/usr/src/lib/libc/net/common",
    135 	"/usr/src/lib/libc/net/inet",
    136 	"/usr/src/lib/libc/net/misc",
    137 	"/usr/src/ucb/pascal",
    138 	"/usr/src/ucb/pascal/utilities",
    139 	"/usr/src/undoc",
    140 #endif
    141 	0
    142 };
    143 
    144 char	sflag = 1;
    145 char	bflag = 1;
    146 char	mflag = 1;
    147 char	**Sflag;
    148 int	Scnt;
    149 char	**Bflag;
    150 int	Bcnt;
    151 char	**Mflag;
    152 int	Mcnt;
    153 char	uflag;
    154 /*
    155  * whereis name
    156  * look for source, documentation and binaries
    157  */
    158 main(argc, argv)
    159 	int argc;
    160 	char *argv[];
    161 {
    162 
    163 	argc--, argv++;
    164 	if (argc == 0) {
    165 usage:
    166 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
    167 		exit(1);
    168 	}
    169 	do
    170 		if (argv[0][0] == '-') {
    171 			register char *cp = argv[0] + 1;
    172 			while (*cp) switch (*cp++) {
    173 
    174 			case 'f':
    175 				break;
    176 
    177 			case 'S':
    178 				getlist(&argc, &argv, &Sflag, &Scnt);
    179 				break;
    180 
    181 			case 'B':
    182 				getlist(&argc, &argv, &Bflag, &Bcnt);
    183 				break;
    184 
    185 			case 'M':
    186 				getlist(&argc, &argv, &Mflag, &Mcnt);
    187 				break;
    188 
    189 			case 's':
    190 				zerof();
    191 				sflag++;
    192 				continue;
    193 
    194 			case 'u':
    195 				uflag++;
    196 				continue;
    197 
    198 			case 'b':
    199 				zerof();
    200 				bflag++;
    201 				continue;
    202 
    203 			case 'm':
    204 				zerof();
    205 				mflag++;
    206 				continue;
    207 
    208 			default:
    209 				goto usage;
    210 			}
    211 			argv++;
    212 		} else
    213 			lookup(*argv++);
    214 	while (--argc > 0);
    215 	exit(0);
    216 }
    217 
    218 getlist(argcp, argvp, flagp, cntp)
    219 	char ***argvp;
    220 	int *argcp;
    221 	char ***flagp;
    222 	int *cntp;
    223 {
    224 
    225 	(*argvp)++;
    226 	*flagp = *argvp;
    227 	*cntp = 0;
    228 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
    229 		(*cntp)++, (*argvp)++;
    230 	(*argcp)++;
    231 	(*argvp)--;
    232 }
    233 
    234 
    235 zerof()
    236 {
    237 
    238 	if (sflag && bflag && mflag)
    239 		sflag = bflag = mflag = 0;
    240 }
    241 int	count;
    242 int	print;
    243 
    244 
    245 lookup(cp)
    246 	register char *cp;
    247 {
    248 	register char *dp;
    249 
    250 	for (dp = cp; *dp; dp++)
    251 		continue;
    252 	for (; dp > cp; dp--) {
    253 		if (*dp == '.') {
    254 			*dp = 0;
    255 			break;
    256 		}
    257 	}
    258 	for (dp = cp; *dp; dp++)
    259 		if (*dp == '/')
    260 			cp = dp + 1;
    261 	if (uflag) {
    262 		print = 0;
    263 		count = 0;
    264 	} else
    265 		print = 1;
    266 again:
    267 	if (print)
    268 		printf("%s:", cp);
    269 	if (sflag) {
    270 		looksrc(cp);
    271 		if (uflag && print == 0 && count != 1) {
    272 			print = 1;
    273 			goto again;
    274 		}
    275 	}
    276 	count = 0;
    277 	if (bflag) {
    278 		lookbin(cp);
    279 		if (uflag && print == 0 && count != 1) {
    280 			print = 1;
    281 			goto again;
    282 		}
    283 	}
    284 	count = 0;
    285 	if (mflag) {
    286 		lookman(cp);
    287 		if (uflag && print == 0 && count != 1) {
    288 			print = 1;
    289 			goto again;
    290 		}
    291 	}
    292 	if (print)
    293 		printf("\n");
    294 }
    295 
    296 looksrc(cp)
    297 	char *cp;
    298 {
    299 	if (Sflag == 0) {
    300 		find(srcdirs, cp);
    301 	} else
    302 		findv(Sflag, Scnt, cp);
    303 }
    304 
    305 lookbin(cp)
    306 	char *cp;
    307 {
    308 	if (Bflag == 0)
    309 		find(bindirs, cp);
    310 	else
    311 		findv(Bflag, Bcnt, cp);
    312 }
    313 
    314 lookman(cp)
    315 	char *cp;
    316 {
    317 	if (Mflag == 0) {
    318 		find(mandirs, cp);
    319 	} else
    320 		findv(Mflag, Mcnt, cp);
    321 }
    322 
    323 findv(dirv, dirc, cp)
    324 	char **dirv;
    325 	int dirc;
    326 	char *cp;
    327 {
    328 
    329 	while (dirc > 0)
    330 		findin(*dirv++, cp), dirc--;
    331 }
    332 
    333 find(dirs, cp)
    334 	char **dirs;
    335 	char *cp;
    336 {
    337 
    338 	while (*dirs)
    339 		findin(*dirs++, cp);
    340 }
    341 
    342 findin(dir, cp)
    343 	char *dir, *cp;
    344 {
    345 	DIR *dirp;
    346 	struct direct *dp;
    347 
    348 	dirp = opendir(dir);
    349 	if (dirp == NULL)
    350 		return;
    351 	while ((dp = readdir(dirp)) != NULL) {
    352 		if (itsit(cp, dp->d_name)) {
    353 			count++;
    354 			if (print)
    355 				printf(" %s/%s", dir, dp->d_name);
    356 		}
    357 	}
    358 	closedir(dirp);
    359 }
    360 
    361 itsit(cp, dp)
    362 	register char *cp, *dp;
    363 {
    364 	register int i = strlen(dp);
    365 
    366 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
    367 		return (1);
    368 	while (*cp && *dp && *cp == *dp)
    369 		cp++, dp++, i--;
    370 	if (*cp == 0 && *dp == 0)
    371 		return (1);
    372 	while (isdigit(*dp))
    373 		dp++;
    374 	if (*cp == 0 && *dp++ == '.') {
    375 		--i;
    376 		while (i > 0 && *dp)
    377 			if (--i, *dp++ == '.')
    378 				return (*dp++ == 'C' && *dp++ == 0);
    379 		return (1);
    380 	}
    381 	return (0);
    382 }
    383