1*12201Ssam static char *sccsid = "@(#)whereis.c 4.9 (Berkeley) 05/03/83"; 26206Sroot 36732Smckusick #include <sys/param.h> 41163Sbill #include <stdio.h> 51163Sbill #include <ctype.h> 66732Smckusick #include <dir.h> 71163Sbill 81163Sbill static char *bindirs[] = { 91163Sbill "/etc", 101163Sbill "/bin", 111163Sbill "/usr/bin", 121163Sbill "/usr/games", 132371Skre "/lib", 142371Skre "/usr/ucb", 152371Skre "/usr/lib", 162371Skre "/usr/local", 172371Skre "/usr/new", 182371Skre "/usr/old", 196732Smckusick "/usr/hosts", 20*12201Ssam "/usr/include", 211163Sbill 0 221163Sbill }; 231163Sbill static char *mandirs[] = { 241163Sbill "/usr/man/man1", 251163Sbill "/usr/man/man2", 261163Sbill "/usr/man/man3", 271163Sbill "/usr/man/man4", 281163Sbill "/usr/man/man5", 291163Sbill "/usr/man/man6", 301163Sbill "/usr/man/man7", 311163Sbill "/usr/man/man8", 321163Sbill 0 331163Sbill }; 341163Sbill static char *srcdirs[] = { 356732Smckusick "/usr/src/bin", 366732Smckusick "/usr/src/usr.bin", 3710723Smckusick "/usr/src/etc", 3810723Smckusick "/usr/src/ucb", 391163Sbill "/usr/src/games", 4010723Smckusick "/usr/src/usr.lib", 416732Smckusick "/usr/src/lib", 4210723Smckusick "/usr/src/local", 4310723Smckusick "/usr/src/new", 4410723Smckusick "/usr/src/old", 45*12201Ssam "/usr/src/include", 466732Smckusick "/usr/src/lib/libc/gen", 476732Smckusick "/usr/src/lib/libc/stdio", 486732Smckusick "/usr/src/lib/libc/sys", 4910723Smckusick "/usr/src/lib/libc/net/common", 5010723Smckusick "/usr/src/lib/libc/net/inet", 5110723Smckusick "/usr/src/lib/libc/net/misc", 5210723Smckusick "/usr/src/ucb/pascal", 5310723Smckusick "/usr/src/ucb/pascal/utilities", 542371Skre "/usr/src/undoc", 551163Sbill 0 561163Sbill }; 571163Sbill 581163Sbill char sflag = 1; 591163Sbill char bflag = 1; 601163Sbill char mflag = 1; 611163Sbill char **Sflag; 621163Sbill int Scnt; 631163Sbill char **Bflag; 641163Sbill int Bcnt; 651163Sbill char **Mflag; 661163Sbill int Mcnt; 671163Sbill char uflag; 681163Sbill /* 691163Sbill * whereis name 701163Sbill * look for source, documentation and binaries 711163Sbill */ 721163Sbill main(argc, argv) 731163Sbill int argc; 741163Sbill char *argv[]; 751163Sbill { 761163Sbill 771163Sbill argc--, argv++; 781163Sbill if (argc == 0) { 791163Sbill usage: 801163Sbill fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); 811163Sbill exit(1); 821163Sbill } 831163Sbill do 841163Sbill if (argv[0][0] == '-') { 851163Sbill register char *cp = argv[0] + 1; 861163Sbill while (*cp) switch (*cp++) { 871163Sbill 881163Sbill case 'f': 891163Sbill break; 901163Sbill 911163Sbill case 'S': 921163Sbill getlist(&argc, &argv, &Sflag, &Scnt); 931163Sbill break; 941163Sbill 951163Sbill case 'B': 961163Sbill getlist(&argc, &argv, &Bflag, &Bcnt); 971163Sbill break; 981163Sbill 991163Sbill case 'M': 1001163Sbill getlist(&argc, &argv, &Mflag, &Mcnt); 1011163Sbill break; 1021163Sbill 1031163Sbill case 's': 1041163Sbill zerof(); 1051163Sbill sflag++; 1061163Sbill continue; 1071163Sbill 1081163Sbill case 'u': 1091163Sbill uflag++; 1101163Sbill continue; 1111163Sbill 1121163Sbill case 'b': 1131163Sbill zerof(); 1141163Sbill bflag++; 1151163Sbill continue; 1161163Sbill 1171163Sbill case 'm': 1181163Sbill zerof(); 1191163Sbill mflag++; 1201163Sbill continue; 1211163Sbill 1221163Sbill default: 1231163Sbill goto usage; 1241163Sbill } 1251163Sbill argv++; 1261163Sbill } else 1271163Sbill lookup(*argv++); 1281163Sbill while (--argc > 0); 1291163Sbill } 1301163Sbill 1311163Sbill getlist(argcp, argvp, flagp, cntp) 1321163Sbill char ***argvp; 1331163Sbill int *argcp; 1341163Sbill char ***flagp; 1351163Sbill int *cntp; 1361163Sbill { 1371163Sbill 1381163Sbill (*argvp)++; 1391163Sbill *flagp = *argvp; 1401163Sbill *cntp = 0; 1411163Sbill for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 1421163Sbill (*cntp)++, (*argvp)++; 1431163Sbill (*argcp)++; 1441163Sbill (*argvp)--; 1451163Sbill } 1461163Sbill 1471163Sbill 1481163Sbill zerof() 1491163Sbill { 1501163Sbill 1511163Sbill if (sflag && bflag && mflag) 1521163Sbill sflag = bflag = mflag = 0; 1531163Sbill } 1541163Sbill int count; 1551163Sbill int print; 1561163Sbill 1571163Sbill 1581163Sbill lookup(cp) 1591163Sbill register char *cp; 1601163Sbill { 1611163Sbill register char *dp; 1621163Sbill 1631163Sbill for (dp = cp; *dp; dp++) 1641163Sbill continue; 1651163Sbill for (; dp > cp; dp--) { 1661163Sbill if (*dp == '.') { 1671163Sbill *dp = 0; 1681163Sbill break; 1691163Sbill } 1701163Sbill } 1711163Sbill for (dp = cp; *dp; dp++) 1721163Sbill if (*dp == '/') 1731163Sbill cp = dp + 1; 1741163Sbill if (uflag) { 1751163Sbill print = 0; 1761163Sbill count = 0; 1771163Sbill } else 1781163Sbill print = 1; 1791163Sbill again: 1801163Sbill if (print) 1811163Sbill printf("%s:", cp); 1821163Sbill if (sflag) { 1831163Sbill looksrc(cp); 1841163Sbill if (uflag && print == 0 && count != 1) { 1851163Sbill print = 1; 1861163Sbill goto again; 1871163Sbill } 1881163Sbill } 1891163Sbill count = 0; 1901163Sbill if (bflag) { 1911163Sbill lookbin(cp); 1921163Sbill if (uflag && print == 0 && count != 1) { 1931163Sbill print = 1; 1941163Sbill goto again; 1951163Sbill } 1961163Sbill } 1971163Sbill count = 0; 1981163Sbill if (mflag) { 1991163Sbill lookman(cp); 2001163Sbill if (uflag && print == 0 && count != 1) { 2011163Sbill print = 1; 2021163Sbill goto again; 2031163Sbill } 2041163Sbill } 2051163Sbill if (print) 2061163Sbill printf("\n"); 2071163Sbill } 2081163Sbill 2091163Sbill looksrc(cp) 2101163Sbill char *cp; 2111163Sbill { 2121163Sbill if (Sflag == 0) { 2131163Sbill find(srcdirs, cp); 2141163Sbill } else 2151163Sbill findv(Sflag, Scnt, cp); 2161163Sbill } 2171163Sbill 2181163Sbill lookbin(cp) 2191163Sbill char *cp; 2201163Sbill { 2211163Sbill if (Bflag == 0) 2221163Sbill find(bindirs, cp); 2231163Sbill else 2241163Sbill findv(Bflag, Bcnt, cp); 2251163Sbill } 2261163Sbill 2271163Sbill lookman(cp) 2281163Sbill char *cp; 2291163Sbill { 2301163Sbill if (Mflag == 0) { 2311163Sbill find(mandirs, cp); 2321163Sbill } else 2331163Sbill findv(Mflag, Mcnt, cp); 2341163Sbill } 2351163Sbill 2361163Sbill findv(dirv, dirc, cp) 2371163Sbill char **dirv; 2381163Sbill int dirc; 2391163Sbill char *cp; 2401163Sbill { 2411163Sbill 2421163Sbill while (dirc > 0) 2431163Sbill findin(*dirv++, cp), dirc--; 2441163Sbill } 2451163Sbill 2461163Sbill find(dirs, cp) 2471163Sbill char **dirs; 2481163Sbill char *cp; 2491163Sbill { 2501163Sbill 2511163Sbill while (*dirs) 2521163Sbill findin(*dirs++, cp); 2531163Sbill } 2541163Sbill 2551163Sbill findin(dir, cp) 2561163Sbill char *dir, *cp; 2571163Sbill { 2586732Smckusick DIR *dirp; 2596732Smckusick struct direct *dp; 2601163Sbill 2616732Smckusick dirp = opendir(dir); 2626732Smckusick if (dirp == NULL) 2631163Sbill return; 2646732Smckusick while ((dp = readdir(dirp)) != NULL) { 2656732Smckusick if (itsit(cp, dp->d_name)) { 2661163Sbill count++; 2671163Sbill if (print) 26810723Smckusick printf(" %s/%s", dir, dp->d_name); 2691163Sbill } 2701163Sbill } 2716732Smckusick closedir(dirp); 2721163Sbill } 2731163Sbill 2741163Sbill itsit(cp, dp) 2751163Sbill register char *cp, *dp; 2761163Sbill { 27710723Smckusick register int i = strlen(dp); 2781163Sbill 2791163Sbill if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 2801163Sbill return (1); 2811163Sbill while (*cp && *dp && *cp == *dp) 2821163Sbill cp++, dp++, i--; 2831163Sbill if (*cp == 0 && *dp == 0) 2841163Sbill return (1); 2851163Sbill while (isdigit(*dp)) 2861163Sbill dp++; 2871163Sbill if (*cp == 0 && *dp++ == '.') { 2881163Sbill --i; 2891163Sbill while (i > 0 && *dp) 2901163Sbill if (--i, *dp++ == '.') 2911163Sbill return (*dp++ == 'C' && *dp++ == 0); 2921163Sbill return (1); 2931163Sbill } 2941163Sbill return (0); 2951163Sbill } 296