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 #pragma ident "%Z%%M% %I% %E% SMI"
137c478bd9Sstevel@tonic-gate
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate #include <sys/param.h>
167c478bd9Sstevel@tonic-gate #include <dirent.h>
177c478bd9Sstevel@tonic-gate #include <stdio.h>
187c478bd9Sstevel@tonic-gate #include <ctype.h>
197c478bd9Sstevel@tonic-gate
207c478bd9Sstevel@tonic-gate static char *bindirs[] = {
217c478bd9Sstevel@tonic-gate "/etc",
227c478bd9Sstevel@tonic-gate "/sbin",
237c478bd9Sstevel@tonic-gate "/usr/bin",
247c478bd9Sstevel@tonic-gate "/usr/ccs/bin",
257c478bd9Sstevel@tonic-gate "/usr/ccs/lib",
267c478bd9Sstevel@tonic-gate "/usr/lang",
277c478bd9Sstevel@tonic-gate "/usr/lbin",
287c478bd9Sstevel@tonic-gate "/usr/lib",
297c478bd9Sstevel@tonic-gate "/usr/sbin",
307c478bd9Sstevel@tonic-gate "/usr/ucb",
317c478bd9Sstevel@tonic-gate "/usr/ucblib",
327c478bd9Sstevel@tonic-gate "/usr/ucbinclude",
337c478bd9Sstevel@tonic-gate "/usr/games",
347c478bd9Sstevel@tonic-gate "/usr/local",
357c478bd9Sstevel@tonic-gate "/usr/local/bin",
367c478bd9Sstevel@tonic-gate "/usr/new",
377c478bd9Sstevel@tonic-gate "/usr/old",
387c478bd9Sstevel@tonic-gate "/usr/hosts",
397c478bd9Sstevel@tonic-gate "/usr/include",
407c478bd9Sstevel@tonic-gate "/usr/etc",
417c478bd9Sstevel@tonic-gate 0
427c478bd9Sstevel@tonic-gate };
437c478bd9Sstevel@tonic-gate static char *mandirs[] = {
447c478bd9Sstevel@tonic-gate "/usr/man/man1",
457c478bd9Sstevel@tonic-gate "/usr/man/man1b",
467c478bd9Sstevel@tonic-gate "/usr/man/man1c",
477c478bd9Sstevel@tonic-gate "/usr/man/man1f",
487c478bd9Sstevel@tonic-gate "/usr/man/man1m",
497c478bd9Sstevel@tonic-gate "/usr/man/man1s",
507c478bd9Sstevel@tonic-gate "/usr/man/man2",
517c478bd9Sstevel@tonic-gate "/usr/man/man3",
527c478bd9Sstevel@tonic-gate "/usr/man/man3b",
537c478bd9Sstevel@tonic-gate "/usr/man/man3c",
547c478bd9Sstevel@tonic-gate "/usr/man/man3e",
557c478bd9Sstevel@tonic-gate "/usr/man/man3g",
567c478bd9Sstevel@tonic-gate "/usr/man/man3j",
577c478bd9Sstevel@tonic-gate "/usr/man/man3k",
587c478bd9Sstevel@tonic-gate "/usr/man/man3l",
597c478bd9Sstevel@tonic-gate "/usr/man/man3m",
607c478bd9Sstevel@tonic-gate "/usr/man/man3n",
617c478bd9Sstevel@tonic-gate "/usr/man/man3s",
627c478bd9Sstevel@tonic-gate "/usr/man/man3w",
637c478bd9Sstevel@tonic-gate "/usr/man/man3x",
647c478bd9Sstevel@tonic-gate "/usr/man/man3x11",
657c478bd9Sstevel@tonic-gate "/usr/man/man3xt",
667c478bd9Sstevel@tonic-gate "/usr/man/man4",
677c478bd9Sstevel@tonic-gate "/usr/man/man4b",
687c478bd9Sstevel@tonic-gate "/usr/man/man5",
697c478bd9Sstevel@tonic-gate "/usr/man/man6",
707c478bd9Sstevel@tonic-gate "/usr/man/man7",
717c478bd9Sstevel@tonic-gate "/usr/man/man7b",
727c478bd9Sstevel@tonic-gate "/usr/man/man8",
737c478bd9Sstevel@tonic-gate "/usr/man/man9e",
747c478bd9Sstevel@tonic-gate "/usr/man/man9f",
757c478bd9Sstevel@tonic-gate "/usr/man/man9s",
767c478bd9Sstevel@tonic-gate "/usr/man/manl",
777c478bd9Sstevel@tonic-gate "/usr/man/mann",
787c478bd9Sstevel@tonic-gate "/usr/man/mano",
797c478bd9Sstevel@tonic-gate 0
807c478bd9Sstevel@tonic-gate };
817c478bd9Sstevel@tonic-gate static char *srcdirs[] = {
827c478bd9Sstevel@tonic-gate "/usr/src/cmd",
837c478bd9Sstevel@tonic-gate "/usr/src/head",
847c478bd9Sstevel@tonic-gate "/usr/src/lib",
857c478bd9Sstevel@tonic-gate "/usr/src/lib/libc",
867c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/port",
877c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/port/gen",
887c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/port/print",
897c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/port/stdio",
907c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/port/sys",
917c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/sparc",
927c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/sparc/gen",
937c478bd9Sstevel@tonic-gate "/usr/src/lib/libc/sparc/sys",
947c478bd9Sstevel@tonic-gate "/usr/src/ucbcmd",
957c478bd9Sstevel@tonic-gate "/usr/src/ucblib",
967c478bd9Sstevel@tonic-gate "/usr/src/ucbinclude",
977c478bd9Sstevel@tonic-gate "/usr/src/uts",
987c478bd9Sstevel@tonic-gate "/usr/src/uts/common",
997c478bd9Sstevel@tonic-gate "/usr/src/uts/sun",
1007c478bd9Sstevel@tonic-gate "/usr/src/uts/sun4",
1017c478bd9Sstevel@tonic-gate "/usr/src/uts/sun4c",
1027c478bd9Sstevel@tonic-gate "/usr/src/uts/sparc",
1037c478bd9Sstevel@tonic-gate "/usr/src/local",
1047c478bd9Sstevel@tonic-gate "/usr/src/new",
1057c478bd9Sstevel@tonic-gate "/usr/src/old",
1067c478bd9Sstevel@tonic-gate 0
1077c478bd9Sstevel@tonic-gate };
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate char sflag = 1;
1107c478bd9Sstevel@tonic-gate char bflag = 1;
1117c478bd9Sstevel@tonic-gate char mflag = 1;
1127c478bd9Sstevel@tonic-gate char **Sflag;
1137c478bd9Sstevel@tonic-gate int Scnt;
1147c478bd9Sstevel@tonic-gate char **Bflag;
1157c478bd9Sstevel@tonic-gate int Bcnt;
1167c478bd9Sstevel@tonic-gate char **Mflag;
1177c478bd9Sstevel@tonic-gate int Mcnt;
1187c478bd9Sstevel@tonic-gate char uflag;
119*cc6c5292Schin
120*cc6c5292Schin void getlist(int *, char ***, char ***, int *);
121*cc6c5292Schin void zerof(void);
122*cc6c5292Schin void lookup(char *);
123*cc6c5292Schin void looksrc(char *);
124*cc6c5292Schin void lookbin(char *);
125*cc6c5292Schin void lookman(char *);
126*cc6c5292Schin void findv(char **, int, char *);
127*cc6c5292Schin void find(char **, char *);
128*cc6c5292Schin void findin(char *, char *);
129*cc6c5292Schin
1307c478bd9Sstevel@tonic-gate /*
1317c478bd9Sstevel@tonic-gate * whereis name
1327c478bd9Sstevel@tonic-gate * look for source, documentation and binaries
1337c478bd9Sstevel@tonic-gate */
134*cc6c5292Schin int
main(int argc,char * argv[])135*cc6c5292Schin main(int argc, char *argv[])
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate argc--, argv++;
1397c478bd9Sstevel@tonic-gate if (argc == 0) {
1407c478bd9Sstevel@tonic-gate usage:
141*cc6c5292Schin fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] "
142*cc6c5292Schin "name...\n");
1437c478bd9Sstevel@tonic-gate exit(1);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate do
1467c478bd9Sstevel@tonic-gate if (argv[0][0] == '-') {
147*cc6c5292Schin char *cp = argv[0] + 1;
148*cc6c5292Schin while (*cp) {
149*cc6c5292Schin
150*cc6c5292Schin switch (*cp++) {
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate case 'f':
1537c478bd9Sstevel@tonic-gate break;
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate case 'S':
1567c478bd9Sstevel@tonic-gate getlist(&argc, &argv, &Sflag, &Scnt);
1577c478bd9Sstevel@tonic-gate break;
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate case 'B':
1607c478bd9Sstevel@tonic-gate getlist(&argc, &argv, &Bflag, &Bcnt);
1617c478bd9Sstevel@tonic-gate break;
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate case 'M':
1647c478bd9Sstevel@tonic-gate getlist(&argc, &argv, &Mflag, &Mcnt);
1657c478bd9Sstevel@tonic-gate break;
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate case 's':
1687c478bd9Sstevel@tonic-gate zerof();
1697c478bd9Sstevel@tonic-gate sflag++;
1707c478bd9Sstevel@tonic-gate continue;
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate case 'u':
1737c478bd9Sstevel@tonic-gate uflag++;
1747c478bd9Sstevel@tonic-gate continue;
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate case 'b':
1777c478bd9Sstevel@tonic-gate zerof();
1787c478bd9Sstevel@tonic-gate bflag++;
1797c478bd9Sstevel@tonic-gate continue;
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate case 'm':
1827c478bd9Sstevel@tonic-gate zerof();
1837c478bd9Sstevel@tonic-gate mflag++;
1847c478bd9Sstevel@tonic-gate continue;
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate default:
1877c478bd9Sstevel@tonic-gate goto usage;
1887c478bd9Sstevel@tonic-gate }
189*cc6c5292Schin }
1907c478bd9Sstevel@tonic-gate argv++;
1917c478bd9Sstevel@tonic-gate } else
1927c478bd9Sstevel@tonic-gate lookup(*argv++);
1937c478bd9Sstevel@tonic-gate while (--argc > 0);
194*cc6c5292Schin return (0);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate
197*cc6c5292Schin void
getlist(int * argcp,char *** argvp,char *** flagp,int * cntp)198*cc6c5292Schin getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate (*argvp)++;
2027c478bd9Sstevel@tonic-gate *flagp = *argvp;
2037c478bd9Sstevel@tonic-gate *cntp = 0;
2047c478bd9Sstevel@tonic-gate for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
2057c478bd9Sstevel@tonic-gate (*cntp)++, (*argvp)++;
2067c478bd9Sstevel@tonic-gate (*argcp)++;
2077c478bd9Sstevel@tonic-gate (*argvp)--;
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate
210*cc6c5292Schin void
zerof(void)211*cc6c5292Schin zerof(void)
2127c478bd9Sstevel@tonic-gate {
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate if (sflag && bflag && mflag)
2157c478bd9Sstevel@tonic-gate sflag = bflag = mflag = 0;
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate int count;
2187c478bd9Sstevel@tonic-gate int print;
2197c478bd9Sstevel@tonic-gate
220*cc6c5292Schin void
lookup(char * cp)221*cc6c5292Schin lookup(char *cp)
2227c478bd9Sstevel@tonic-gate {
223*cc6c5292Schin char *dp;
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate for (dp = cp; *dp; dp++)
2267c478bd9Sstevel@tonic-gate continue;
2277c478bd9Sstevel@tonic-gate for (; dp > cp; dp--) {
2287c478bd9Sstevel@tonic-gate if (*dp == '.') {
2297c478bd9Sstevel@tonic-gate *dp = 0;
2307c478bd9Sstevel@tonic-gate break;
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate for (dp = cp; *dp; dp++)
2347c478bd9Sstevel@tonic-gate if (*dp == '/')
2357c478bd9Sstevel@tonic-gate cp = dp + 1;
2367c478bd9Sstevel@tonic-gate if (uflag) {
2377c478bd9Sstevel@tonic-gate print = 0;
2387c478bd9Sstevel@tonic-gate count = 0;
2397c478bd9Sstevel@tonic-gate } else
2407c478bd9Sstevel@tonic-gate print = 1;
2417c478bd9Sstevel@tonic-gate again:
2427c478bd9Sstevel@tonic-gate if (print)
2437c478bd9Sstevel@tonic-gate printf("%s:", cp);
2447c478bd9Sstevel@tonic-gate if (sflag) {
2457c478bd9Sstevel@tonic-gate looksrc(cp);
2467c478bd9Sstevel@tonic-gate if (uflag && print == 0 && count != 1) {
2477c478bd9Sstevel@tonic-gate print = 1;
2487c478bd9Sstevel@tonic-gate goto again;
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate count = 0;
2527c478bd9Sstevel@tonic-gate if (bflag) {
2537c478bd9Sstevel@tonic-gate lookbin(cp);
2547c478bd9Sstevel@tonic-gate if (uflag && print == 0 && count != 1) {
2557c478bd9Sstevel@tonic-gate print = 1;
2567c478bd9Sstevel@tonic-gate goto again;
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate count = 0;
2607c478bd9Sstevel@tonic-gate if (mflag) {
2617c478bd9Sstevel@tonic-gate lookman(cp);
2627c478bd9Sstevel@tonic-gate if (uflag && print == 0 && count != 1) {
2637c478bd9Sstevel@tonic-gate print = 1;
2647c478bd9Sstevel@tonic-gate goto again;
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate if (print)
2687c478bd9Sstevel@tonic-gate printf("\n");
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate
271*cc6c5292Schin void
looksrc(char * cp)272*cc6c5292Schin looksrc(char *cp)
2737c478bd9Sstevel@tonic-gate {
2747c478bd9Sstevel@tonic-gate if (Sflag == 0) {
2757c478bd9Sstevel@tonic-gate find(srcdirs, cp);
2767c478bd9Sstevel@tonic-gate } else
2777c478bd9Sstevel@tonic-gate findv(Sflag, Scnt, cp);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate
280*cc6c5292Schin void
lookbin(char * cp)281*cc6c5292Schin lookbin(char *cp)
2827c478bd9Sstevel@tonic-gate {
2837c478bd9Sstevel@tonic-gate if (Bflag == 0)
2847c478bd9Sstevel@tonic-gate find(bindirs, cp);
2857c478bd9Sstevel@tonic-gate else
2867c478bd9Sstevel@tonic-gate findv(Bflag, Bcnt, cp);
2877c478bd9Sstevel@tonic-gate }
2887c478bd9Sstevel@tonic-gate
289*cc6c5292Schin void
lookman(char * cp)290*cc6c5292Schin lookman(char *cp)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate if (Mflag == 0) {
2937c478bd9Sstevel@tonic-gate find(mandirs, cp);
2947c478bd9Sstevel@tonic-gate } else
2957c478bd9Sstevel@tonic-gate findv(Mflag, Mcnt, cp);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate
298*cc6c5292Schin void
findv(char ** dirv,int dirc,char * cp)299*cc6c5292Schin findv(char **dirv, int dirc, char *cp)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate while (dirc > 0)
3037c478bd9Sstevel@tonic-gate findin(*dirv++, cp), dirc--;
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate
306*cc6c5292Schin void
find(char ** dirs,char * cp)307*cc6c5292Schin find(char **dirs, char *cp)
3087c478bd9Sstevel@tonic-gate {
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate while (*dirs)
3117c478bd9Sstevel@tonic-gate findin(*dirs++, cp);
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
314*cc6c5292Schin void
findin(char * dir,char * cp)315*cc6c5292Schin findin(char *dir, char *cp)
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate DIR *dirp;
3187c478bd9Sstevel@tonic-gate struct dirent *dp;
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate dirp = opendir(dir);
3217c478bd9Sstevel@tonic-gate if (dirp == NULL)
3227c478bd9Sstevel@tonic-gate return;
3237c478bd9Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) {
3247c478bd9Sstevel@tonic-gate if (itsit(cp, dp->d_name)) {
3257c478bd9Sstevel@tonic-gate count++;
3267c478bd9Sstevel@tonic-gate if (print)
3277c478bd9Sstevel@tonic-gate printf(" %s/%s", dir, dp->d_name);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate closedir(dirp);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
333*cc6c5292Schin int
itsit(char * cp,char * dp)334*cc6c5292Schin itsit(char *cp, char *dp)
3357c478bd9Sstevel@tonic-gate {
336*cc6c5292Schin int i = strlen(dp);
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
3397c478bd9Sstevel@tonic-gate return (1);
3407c478bd9Sstevel@tonic-gate while (*cp && *dp && *cp == *dp)
3417c478bd9Sstevel@tonic-gate cp++, dp++, i--;
3427c478bd9Sstevel@tonic-gate if (*cp == 0 && *dp == 0)
3437c478bd9Sstevel@tonic-gate return (1);
3447c478bd9Sstevel@tonic-gate while (isdigit(*dp))
3457c478bd9Sstevel@tonic-gate dp++;
3467c478bd9Sstevel@tonic-gate if (*cp == 0 && *dp++ == '.') {
3477c478bd9Sstevel@tonic-gate --i;
3487c478bd9Sstevel@tonic-gate while (i > 0 && *dp)
3497c478bd9Sstevel@tonic-gate if (--i, *dp++ == '.')
3507c478bd9Sstevel@tonic-gate return (*dp++ == 'C' && *dp++ == 0);
3517c478bd9Sstevel@tonic-gate return (1);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate return (0);
3547c478bd9Sstevel@tonic-gate }
355