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