Home | History | Annotate | Download | only in whereis
      1 /*
      2  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * Copyright (c) 1980 Regents of the University of California.
      8  * All rights reserved.  The Berkeley software License Agreement
      9  * specifies the terms and conditions for redistribution.
     10  */
     11 
     12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     13 
     14 
     15 #include <sys/param.h>
     16 #include <dirent.h>
     17 #include <stdio.h>
     18 #include <ctype.h>
     19 
     20 static char *bindirs[] = {
     21 	"/etc",
     22 	"/sbin",
     23 	"/usr/bin",
     24 	"/usr/ccs/bin",
     25 	"/usr/ccs/lib",
     26 	"/usr/lang",
     27 	"/usr/lbin",
     28 	"/usr/lib",
     29 	"/usr/sbin",
     30 	"/usr/ucb",
     31 	"/usr/ucblib",
     32 	"/usr/ucbinclude",
     33 	"/usr/games",
     34 	"/usr/local",
     35 	"/usr/local/bin",
     36 	"/usr/new",
     37 	"/usr/old",
     38 	"/usr/hosts",
     39 	"/usr/include",
     40 	"/usr/etc",
     41 	0
     42 };
     43 static char *mandirs[] = {
     44 	"/usr/man/man1",
     45 	"/usr/man/man1b",
     46 	"/usr/man/man1c",
     47 	"/usr/man/man1f",
     48 	"/usr/man/man1m",
     49 	"/usr/man/man1s",
     50 	"/usr/man/man2",
     51 	"/usr/man/man3",
     52 	"/usr/man/man3b",
     53 	"/usr/man/man3c",
     54 	"/usr/man/man3e",
     55 	"/usr/man/man3g",
     56 	"/usr/man/man3j",
     57 	"/usr/man/man3k",
     58 	"/usr/man/man3l",
     59 	"/usr/man/man3m",
     60 	"/usr/man/man3n",
     61 	"/usr/man/man3s",
     62 	"/usr/man/man3w",
     63 	"/usr/man/man3x",
     64 	"/usr/man/man3x11",
     65 	"/usr/man/man3xt",
     66 	"/usr/man/man4",
     67 	"/usr/man/man4b",
     68 	"/usr/man/man5",
     69 	"/usr/man/man6",
     70 	"/usr/man/man7",
     71 	"/usr/man/man7b",
     72 	"/usr/man/man8",
     73 	"/usr/man/man9e",
     74 	"/usr/man/man9f",
     75 	"/usr/man/man9s",
     76 	"/usr/man/manl",
     77 	"/usr/man/mann",
     78 	"/usr/man/mano",
     79 	0
     80 };
     81 static char *srcdirs[]  = {
     82 	"/usr/src/cmd",
     83 	"/usr/src/head",
     84 	"/usr/src/lib",
     85 	"/usr/src/lib/libc",
     86 	"/usr/src/lib/libc/port",
     87 	"/usr/src/lib/libc/port/gen",
     88 	"/usr/src/lib/libc/port/print",
     89 	"/usr/src/lib/libc/port/stdio",
     90 	"/usr/src/lib/libc/port/sys",
     91 	"/usr/src/lib/libc/sparc",
     92 	"/usr/src/lib/libc/sparc/gen",
     93 	"/usr/src/lib/libc/sparc/sys",
     94 	"/usr/src/ucbcmd",
     95 	"/usr/src/ucblib",
     96 	"/usr/src/ucbinclude",
     97 	"/usr/src/uts",
     98 	"/usr/src/uts/common",
     99 	"/usr/src/uts/sun",
    100 	"/usr/src/uts/sun4",
    101 	"/usr/src/uts/sun4c",
    102 	"/usr/src/uts/sparc",
    103 	"/usr/src/local",
    104 	"/usr/src/new",
    105 	"/usr/src/old",
    106 	0
    107 };
    108 
    109 char	sflag = 1;
    110 char	bflag = 1;
    111 char	mflag = 1;
    112 char	**Sflag;
    113 int	Scnt;
    114 char	**Bflag;
    115 int	Bcnt;
    116 char	**Mflag;
    117 int	Mcnt;
    118 char	uflag;
    119 
    120 void getlist(int *, char ***, char ***, int *);
    121 void zerof(void);
    122 void lookup(char *);
    123 void looksrc(char *);
    124 void lookbin(char *);
    125 void lookman(char *);
    126 void findv(char **, int, char *);
    127 void find(char **, char *);
    128 void findin(char *, char *);
    129 
    130 /*
    131  * whereis name
    132  * look for source, documentation and binaries
    133  */
    134 int
    135 main(int argc, char *argv[])
    136 {
    137 
    138 	argc--, argv++;
    139 	if (argc == 0) {
    140 usage:
    141 		fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] "
    142 		    "name...\n");
    143 		exit(1);
    144 	}
    145 	do
    146 		if (argv[0][0] == '-') {
    147 			char *cp = argv[0] + 1;
    148 			while (*cp) {
    149 
    150 				switch (*cp++) {
    151 
    152 			case 'f':
    153 				break;
    154 
    155 			case 'S':
    156 				getlist(&argc, &argv, &Sflag, &Scnt);
    157 				break;
    158 
    159 			case 'B':
    160 				getlist(&argc, &argv, &Bflag, &Bcnt);
    161 				break;
    162 
    163 			case 'M':
    164 				getlist(&argc, &argv, &Mflag, &Mcnt);
    165 				break;
    166 
    167 			case 's':
    168 				zerof();
    169 				sflag++;
    170 				continue;
    171 
    172 			case 'u':
    173 				uflag++;
    174 				continue;
    175 
    176 			case 'b':
    177 				zerof();
    178 				bflag++;
    179 				continue;
    180 
    181 			case 'm':
    182 				zerof();
    183 				mflag++;
    184 				continue;
    185 
    186 			default:
    187 				goto usage;
    188 				}
    189 			}
    190 			argv++;
    191 		} else
    192 			lookup(*argv++);
    193 	while (--argc > 0);
    194 	return (0);
    195 }
    196 
    197 void
    198 getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
    199 {
    200 
    201 	(*argvp)++;
    202 	*flagp = *argvp;
    203 	*cntp = 0;
    204 	for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
    205 		(*cntp)++, (*argvp)++;
    206 	(*argcp)++;
    207 	(*argvp)--;
    208 }
    209 
    210 void
    211 zerof(void)
    212 {
    213 
    214 	if (sflag && bflag && mflag)
    215 		sflag = bflag = mflag = 0;
    216 }
    217 int	count;
    218 int	print;
    219 
    220 void
    221 lookup(char *cp)
    222 {
    223 	char *dp;
    224 
    225 	for (dp = cp; *dp; dp++)
    226 		continue;
    227 	for (; dp > cp; dp--) {
    228 		if (*dp == '.') {
    229 			*dp = 0;
    230 			break;
    231 		}
    232 	}
    233 	for (dp = cp; *dp; dp++)
    234 		if (*dp == '/')
    235 			cp = dp + 1;
    236 	if (uflag) {
    237 		print = 0;
    238 		count = 0;
    239 	} else
    240 		print = 1;
    241 again:
    242 	if (print)
    243 		printf("%s:", cp);
    244 	if (sflag) {
    245 		looksrc(cp);
    246 		if (uflag && print == 0 && count != 1) {
    247 			print = 1;
    248 			goto again;
    249 		}
    250 	}
    251 	count = 0;
    252 	if (bflag) {
    253 		lookbin(cp);
    254 		if (uflag && print == 0 && count != 1) {
    255 			print = 1;
    256 			goto again;
    257 		}
    258 	}
    259 	count = 0;
    260 	if (mflag) {
    261 		lookman(cp);
    262 		if (uflag && print == 0 && count != 1) {
    263 			print = 1;
    264 			goto again;
    265 		}
    266 	}
    267 	if (print)
    268 		printf("\n");
    269 }
    270 
    271 void
    272 looksrc(char *cp)
    273 {
    274 	if (Sflag == 0) {
    275 		find(srcdirs, cp);
    276 	} else
    277 		findv(Sflag, Scnt, cp);
    278 }
    279 
    280 void
    281 lookbin(char *cp)
    282 {
    283 	if (Bflag == 0)
    284 		find(bindirs, cp);
    285 	else
    286 		findv(Bflag, Bcnt, cp);
    287 }
    288 
    289 void
    290 lookman(char *cp)
    291 {
    292 	if (Mflag == 0) {
    293 		find(mandirs, cp);
    294 	} else
    295 		findv(Mflag, Mcnt, cp);
    296 }
    297 
    298 void
    299 findv(char **dirv, int dirc, char *cp)
    300 {
    301 
    302 	while (dirc > 0)
    303 		findin(*dirv++, cp), dirc--;
    304 }
    305 
    306 void
    307 find(char **dirs, char *cp)
    308 {
    309 
    310 	while (*dirs)
    311 		findin(*dirs++, cp);
    312 }
    313 
    314 void
    315 findin(char *dir, char *cp)
    316 {
    317 	DIR *dirp;
    318 	struct dirent *dp;
    319 
    320 	dirp = opendir(dir);
    321 	if (dirp == NULL)
    322 		return;
    323 	while ((dp = readdir(dirp)) != NULL) {
    324 		if (itsit(cp, dp->d_name)) {
    325 			count++;
    326 			if (print)
    327 				printf(" %s/%s", dir, dp->d_name);
    328 		}
    329 	}
    330 	closedir(dirp);
    331 }
    332 
    333 int
    334 itsit(char *cp, char *dp)
    335 {
    336 	int i = strlen(dp);
    337 
    338 	if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
    339 		return (1);
    340 	while (*cp && *dp && *cp == *dp)
    341 		cp++, dp++, i--;
    342 	if (*cp == 0 && *dp == 0)
    343 		return (1);
    344 	while (isdigit(*dp))
    345 		dp++;
    346 	if (*cp == 0 && *dp++ == '.') {
    347 		--i;
    348 		while (i > 0 && *dp)
    349 			if (--i, *dp++ == '.')
    350 				return (*dp++ == 'C' && *dp++ == 0);
    351 		return (1);
    352 	}
    353 	return (0);
    354 }
    355