121590Sdist /* 2*40378Sbostic * Copyright (c) 1980, 1990 The Regents of the University of California. 3*40378Sbostic * All rights reserved. 4*40378Sbostic * 5*40378Sbostic * Redistribution and use in source and binary forms are permitted 6*40378Sbostic * provided that the above copyright notice and this paragraph are 7*40378Sbostic * duplicated in all such forms and that any documentation, 8*40378Sbostic * advertising materials, and other materials related to such 9*40378Sbostic * distribution and use acknowledge that the software was developed 10*40378Sbostic * by the University of California, Berkeley. The name of the 11*40378Sbostic * University may not be used to endorse or promote products derived 12*40378Sbostic * from this software without specific prior written permission. 13*40378Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*40378Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*40378Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621590Sdist */ 1721590Sdist 1813623Ssam #ifndef lint 1921590Sdist char copyright[] = 20*40378Sbostic "@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\ 2121590Sdist All rights reserved.\n"; 2232752Sbostic #endif /* not lint */ 236206Sroot 2421590Sdist #ifndef lint 25*40378Sbostic static char sccsid[] = "@(#)whereis.c 5.3 (Berkeley) 03/10/90"; 2632752Sbostic #endif /* not lint */ 2721590Sdist 286732Smckusick #include <sys/param.h> 2913623Ssam #include <sys/dir.h> 301163Sbill #include <stdio.h> 311163Sbill #include <ctype.h> 321163Sbill 331163Sbill static char *bindirs[] = { 341163Sbill "/etc", 351163Sbill "/bin", 361163Sbill "/usr/bin", 371163Sbill "/usr/games", 382371Skre "/lib", 392371Skre "/usr/ucb", 402371Skre "/usr/lib", 412371Skre "/usr/local", 422371Skre "/usr/new", 432371Skre "/usr/old", 446732Smckusick "/usr/hosts", 4512201Ssam "/usr/include", 461163Sbill 0 471163Sbill }; 481163Sbill static char *mandirs[] = { 491163Sbill "/usr/man/man1", 501163Sbill "/usr/man/man2", 511163Sbill "/usr/man/man3", 521163Sbill "/usr/man/man4", 531163Sbill "/usr/man/man5", 541163Sbill "/usr/man/man6", 551163Sbill "/usr/man/man7", 561163Sbill "/usr/man/man8", 5716077Sralph "/usr/man/manl", 5816077Sralph "/usr/man/mann", 5916077Sralph "/usr/man/mano", 601163Sbill 0 611163Sbill }; 621163Sbill static char *srcdirs[] = { 636732Smckusick "/usr/src/bin", 646732Smckusick "/usr/src/usr.bin", 6510723Smckusick "/usr/src/etc", 6610723Smckusick "/usr/src/ucb", 671163Sbill "/usr/src/games", 6810723Smckusick "/usr/src/usr.lib", 696732Smckusick "/usr/src/lib", 7010723Smckusick "/usr/src/local", 7110723Smckusick "/usr/src/new", 7210723Smckusick "/usr/src/old", 7312201Ssam "/usr/src/include", 746732Smckusick "/usr/src/lib/libc/gen", 756732Smckusick "/usr/src/lib/libc/stdio", 766732Smckusick "/usr/src/lib/libc/sys", 7710723Smckusick "/usr/src/lib/libc/net/common", 7810723Smckusick "/usr/src/lib/libc/net/inet", 7910723Smckusick "/usr/src/lib/libc/net/misc", 8010723Smckusick "/usr/src/ucb/pascal", 8110723Smckusick "/usr/src/ucb/pascal/utilities", 822371Skre "/usr/src/undoc", 831163Sbill 0 841163Sbill }; 851163Sbill 861163Sbill char sflag = 1; 871163Sbill char bflag = 1; 881163Sbill char mflag = 1; 891163Sbill char **Sflag; 901163Sbill int Scnt; 911163Sbill char **Bflag; 921163Sbill int Bcnt; 931163Sbill char **Mflag; 941163Sbill int Mcnt; 951163Sbill char uflag; 961163Sbill /* 971163Sbill * whereis name 981163Sbill * look for source, documentation and binaries 991163Sbill */ 1001163Sbill main(argc, argv) 1011163Sbill int argc; 1021163Sbill char *argv[]; 1031163Sbill { 1041163Sbill 1051163Sbill argc--, argv++; 1061163Sbill if (argc == 0) { 1071163Sbill usage: 1081163Sbill fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); 1091163Sbill exit(1); 1101163Sbill } 1111163Sbill do 1121163Sbill if (argv[0][0] == '-') { 1131163Sbill register char *cp = argv[0] + 1; 1141163Sbill while (*cp) switch (*cp++) { 1151163Sbill 1161163Sbill case 'f': 1171163Sbill break; 1181163Sbill 1191163Sbill case 'S': 1201163Sbill getlist(&argc, &argv, &Sflag, &Scnt); 1211163Sbill break; 1221163Sbill 1231163Sbill case 'B': 1241163Sbill getlist(&argc, &argv, &Bflag, &Bcnt); 1251163Sbill break; 1261163Sbill 1271163Sbill case 'M': 1281163Sbill getlist(&argc, &argv, &Mflag, &Mcnt); 1291163Sbill break; 1301163Sbill 1311163Sbill case 's': 1321163Sbill zerof(); 1331163Sbill sflag++; 1341163Sbill continue; 1351163Sbill 1361163Sbill case 'u': 1371163Sbill uflag++; 1381163Sbill continue; 1391163Sbill 1401163Sbill case 'b': 1411163Sbill zerof(); 1421163Sbill bflag++; 1431163Sbill continue; 1441163Sbill 1451163Sbill case 'm': 1461163Sbill zerof(); 1471163Sbill mflag++; 1481163Sbill continue; 1491163Sbill 1501163Sbill default: 1511163Sbill goto usage; 1521163Sbill } 1531163Sbill argv++; 1541163Sbill } else 1551163Sbill lookup(*argv++); 1561163Sbill while (--argc > 0); 15732752Sbostic exit(0); 1581163Sbill } 1591163Sbill 1601163Sbill getlist(argcp, argvp, flagp, cntp) 1611163Sbill char ***argvp; 1621163Sbill int *argcp; 1631163Sbill char ***flagp; 1641163Sbill int *cntp; 1651163Sbill { 1661163Sbill 1671163Sbill (*argvp)++; 1681163Sbill *flagp = *argvp; 1691163Sbill *cntp = 0; 1701163Sbill for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 1711163Sbill (*cntp)++, (*argvp)++; 1721163Sbill (*argcp)++; 1731163Sbill (*argvp)--; 1741163Sbill } 1751163Sbill 1761163Sbill 1771163Sbill zerof() 1781163Sbill { 1791163Sbill 1801163Sbill if (sflag && bflag && mflag) 1811163Sbill sflag = bflag = mflag = 0; 1821163Sbill } 1831163Sbill int count; 1841163Sbill int print; 1851163Sbill 1861163Sbill 1871163Sbill lookup(cp) 1881163Sbill register char *cp; 1891163Sbill { 1901163Sbill register char *dp; 1911163Sbill 1921163Sbill for (dp = cp; *dp; dp++) 1931163Sbill continue; 1941163Sbill for (; dp > cp; dp--) { 1951163Sbill if (*dp == '.') { 1961163Sbill *dp = 0; 1971163Sbill break; 1981163Sbill } 1991163Sbill } 2001163Sbill for (dp = cp; *dp; dp++) 2011163Sbill if (*dp == '/') 2021163Sbill cp = dp + 1; 2031163Sbill if (uflag) { 2041163Sbill print = 0; 2051163Sbill count = 0; 2061163Sbill } else 2071163Sbill print = 1; 2081163Sbill again: 2091163Sbill if (print) 2101163Sbill printf("%s:", cp); 2111163Sbill if (sflag) { 2121163Sbill looksrc(cp); 2131163Sbill if (uflag && print == 0 && count != 1) { 2141163Sbill print = 1; 2151163Sbill goto again; 2161163Sbill } 2171163Sbill } 2181163Sbill count = 0; 2191163Sbill if (bflag) { 2201163Sbill lookbin(cp); 2211163Sbill if (uflag && print == 0 && count != 1) { 2221163Sbill print = 1; 2231163Sbill goto again; 2241163Sbill } 2251163Sbill } 2261163Sbill count = 0; 2271163Sbill if (mflag) { 2281163Sbill lookman(cp); 2291163Sbill if (uflag && print == 0 && count != 1) { 2301163Sbill print = 1; 2311163Sbill goto again; 2321163Sbill } 2331163Sbill } 2341163Sbill if (print) 2351163Sbill printf("\n"); 2361163Sbill } 2371163Sbill 2381163Sbill looksrc(cp) 2391163Sbill char *cp; 2401163Sbill { 2411163Sbill if (Sflag == 0) { 2421163Sbill find(srcdirs, cp); 2431163Sbill } else 2441163Sbill findv(Sflag, Scnt, cp); 2451163Sbill } 2461163Sbill 2471163Sbill lookbin(cp) 2481163Sbill char *cp; 2491163Sbill { 2501163Sbill if (Bflag == 0) 2511163Sbill find(bindirs, cp); 2521163Sbill else 2531163Sbill findv(Bflag, Bcnt, cp); 2541163Sbill } 2551163Sbill 2561163Sbill lookman(cp) 2571163Sbill char *cp; 2581163Sbill { 2591163Sbill if (Mflag == 0) { 2601163Sbill find(mandirs, cp); 2611163Sbill } else 2621163Sbill findv(Mflag, Mcnt, cp); 2631163Sbill } 2641163Sbill 2651163Sbill findv(dirv, dirc, cp) 2661163Sbill char **dirv; 2671163Sbill int dirc; 2681163Sbill char *cp; 2691163Sbill { 2701163Sbill 2711163Sbill while (dirc > 0) 2721163Sbill findin(*dirv++, cp), dirc--; 2731163Sbill } 2741163Sbill 2751163Sbill find(dirs, cp) 2761163Sbill char **dirs; 2771163Sbill char *cp; 2781163Sbill { 2791163Sbill 2801163Sbill while (*dirs) 2811163Sbill findin(*dirs++, cp); 2821163Sbill } 2831163Sbill 2841163Sbill findin(dir, cp) 2851163Sbill char *dir, *cp; 2861163Sbill { 2876732Smckusick DIR *dirp; 2886732Smckusick struct direct *dp; 2891163Sbill 2906732Smckusick dirp = opendir(dir); 2916732Smckusick if (dirp == NULL) 2921163Sbill return; 2936732Smckusick while ((dp = readdir(dirp)) != NULL) { 2946732Smckusick if (itsit(cp, dp->d_name)) { 2951163Sbill count++; 2961163Sbill if (print) 29710723Smckusick printf(" %s/%s", dir, dp->d_name); 2981163Sbill } 2991163Sbill } 3006732Smckusick closedir(dirp); 3011163Sbill } 3021163Sbill 3031163Sbill itsit(cp, dp) 3041163Sbill register char *cp, *dp; 3051163Sbill { 30610723Smckusick register int i = strlen(dp); 3071163Sbill 3081163Sbill if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 3091163Sbill return (1); 3101163Sbill while (*cp && *dp && *cp == *dp) 3111163Sbill cp++, dp++, i--; 3121163Sbill if (*cp == 0 && *dp == 0) 3131163Sbill return (1); 3141163Sbill while (isdigit(*dp)) 3151163Sbill dp++; 3161163Sbill if (*cp == 0 && *dp++ == '.') { 3171163Sbill --i; 3181163Sbill while (i > 0 && *dp) 3191163Sbill if (--i, *dp++ == '.') 3201163Sbill return (*dp++ == 'C' && *dp++ == 0); 3211163Sbill return (1); 3221163Sbill } 3231163Sbill return (0); 3241163Sbill } 325