1 /*- 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 char copyright[] = 36 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)whereis.c 5.5 (Berkeley) 4/18/91"; 42 #endif /* not lint */ 43 44 #include <sys/param.h> 45 #include <sys/dir.h> 46 #include <stdio.h> 47 #include <ctype.h> 48 49 static char *bindirs[] = { 50 "/bin", 51 "/sbin", 52 "/usr/ucb", 53 "/usr/bin", 54 "/usr/sbin", 55 "/usr/old", 56 "/usr/contrib", 57 "/usr/games", 58 "/usr/local", 59 "/usr/libexec", 60 "/usr/include", 61 "/usr/hosts", 62 "/usr/share", /*?*/ 63 "/etc", 64 #ifdef notdef 65 /* before reorg */ 66 "/etc", 67 "/bin", 68 "/usr/bin", 69 "/usr/games", 70 "/lib", 71 "/usr/ucb", 72 "/usr/lib", 73 "/usr/local", 74 "/usr/new", 75 "/usr/old", 76 "/usr/hosts", 77 "/usr/include", 78 #endif 79 0 80 }; 81 /* This needs to be redone - man pages live with sources */ 82 static char *mandirs[] = { 83 "/usr/man/man1", 84 "/usr/man/man2", 85 "/usr/man/man3", 86 "/usr/man/man4", 87 "/usr/man/man5", 88 "/usr/man/man6", 89 "/usr/man/man7", 90 "/usr/man/man8", 91 "/usr/man/manl", 92 "/usr/man/mann", 93 "/usr/man/mano", 94 0 95 }; 96 static char *srcdirs[] = { 97 "/usr/src/bin", 98 "/usr/src/sbin", 99 "/usr/src/etc", 100 "/usr/src/pgrm", 101 "/usr/src/usr.bin", 102 "/usr/src/usr.sbin", 103 "/usr/src/usr.ucb", 104 "/usr/src/usr.new", 105 "/usr/src/usr.lib", 106 "/usr/src/libexec", 107 "/usr/src/libdata", 108 "/usr/src/share", 109 "/usr/src/contrib", 110 "/usr/src/athena", 111 "/usr/src/devel", 112 "/usr/src/games", 113 "/usr/src/local", 114 "/usr/src/man", 115 "/usr/src/root", 116 "/usr/src/old", 117 "/usr/src/include", 118 /* still need libs */ 119 #ifdef notdef /* before reorg */ 120 "/usr/src/bin", 121 "/usr/src/usr.bin", 122 "/usr/src/etc", 123 "/usr/src/ucb", 124 "/usr/src/games", 125 "/usr/src/usr.lib", 126 "/usr/src/lib", 127 "/usr/src/local", 128 "/usr/src/new", 129 "/usr/src/old", 130 "/usr/src/include", 131 "/usr/src/lib/libc/gen", 132 "/usr/src/lib/libc/stdio", 133 "/usr/src/lib/libc/sys", 134 "/usr/src/lib/libc/net/common", 135 "/usr/src/lib/libc/net/inet", 136 "/usr/src/lib/libc/net/misc", 137 "/usr/src/ucb/pascal", 138 "/usr/src/ucb/pascal/utilities", 139 "/usr/src/undoc", 140 #endif 141 0 142 }; 143 144 char sflag = 1; 145 char bflag = 1; 146 char mflag = 1; 147 char **Sflag; 148 int Scnt; 149 char **Bflag; 150 int Bcnt; 151 char **Mflag; 152 int Mcnt; 153 char uflag; 154 /* 155 * whereis name 156 * look for source, documentation and binaries 157 */ 158 main(argc, argv) 159 int argc; 160 char *argv[]; 161 { 162 163 argc--, argv++; 164 if (argc == 0) { 165 usage: 166 fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); 167 exit(1); 168 } 169 do 170 if (argv[0][0] == '-') { 171 register char *cp = argv[0] + 1; 172 while (*cp) switch (*cp++) { 173 174 case 'f': 175 break; 176 177 case 'S': 178 getlist(&argc, &argv, &Sflag, &Scnt); 179 break; 180 181 case 'B': 182 getlist(&argc, &argv, &Bflag, &Bcnt); 183 break; 184 185 case 'M': 186 getlist(&argc, &argv, &Mflag, &Mcnt); 187 break; 188 189 case 's': 190 zerof(); 191 sflag++; 192 continue; 193 194 case 'u': 195 uflag++; 196 continue; 197 198 case 'b': 199 zerof(); 200 bflag++; 201 continue; 202 203 case 'm': 204 zerof(); 205 mflag++; 206 continue; 207 208 default: 209 goto usage; 210 } 211 argv++; 212 } else 213 lookup(*argv++); 214 while (--argc > 0); 215 exit(0); 216 } 217 218 getlist(argcp, argvp, flagp, cntp) 219 char ***argvp; 220 int *argcp; 221 char ***flagp; 222 int *cntp; 223 { 224 225 (*argvp)++; 226 *flagp = *argvp; 227 *cntp = 0; 228 for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 229 (*cntp)++, (*argvp)++; 230 (*argcp)++; 231 (*argvp)--; 232 } 233 234 235 zerof() 236 { 237 238 if (sflag && bflag && mflag) 239 sflag = bflag = mflag = 0; 240 } 241 int count; 242 int print; 243 244 245 lookup(cp) 246 register char *cp; 247 { 248 register char *dp; 249 250 for (dp = cp; *dp; dp++) 251 continue; 252 for (; dp > cp; dp--) { 253 if (*dp == '.') { 254 *dp = 0; 255 break; 256 } 257 } 258 for (dp = cp; *dp; dp++) 259 if (*dp == '/') 260 cp = dp + 1; 261 if (uflag) { 262 print = 0; 263 count = 0; 264 } else 265 print = 1; 266 again: 267 if (print) 268 printf("%s:", cp); 269 if (sflag) { 270 looksrc(cp); 271 if (uflag && print == 0 && count != 1) { 272 print = 1; 273 goto again; 274 } 275 } 276 count = 0; 277 if (bflag) { 278 lookbin(cp); 279 if (uflag && print == 0 && count != 1) { 280 print = 1; 281 goto again; 282 } 283 } 284 count = 0; 285 if (mflag) { 286 lookman(cp); 287 if (uflag && print == 0 && count != 1) { 288 print = 1; 289 goto again; 290 } 291 } 292 if (print) 293 printf("\n"); 294 } 295 296 looksrc(cp) 297 char *cp; 298 { 299 if (Sflag == 0) { 300 find(srcdirs, cp); 301 } else 302 findv(Sflag, Scnt, cp); 303 } 304 305 lookbin(cp) 306 char *cp; 307 { 308 if (Bflag == 0) 309 find(bindirs, cp); 310 else 311 findv(Bflag, Bcnt, cp); 312 } 313 314 lookman(cp) 315 char *cp; 316 { 317 if (Mflag == 0) { 318 find(mandirs, cp); 319 } else 320 findv(Mflag, Mcnt, cp); 321 } 322 323 findv(dirv, dirc, cp) 324 char **dirv; 325 int dirc; 326 char *cp; 327 { 328 329 while (dirc > 0) 330 findin(*dirv++, cp), dirc--; 331 } 332 333 find(dirs, cp) 334 char **dirs; 335 char *cp; 336 { 337 338 while (*dirs) 339 findin(*dirs++, cp); 340 } 341 342 findin(dir, cp) 343 char *dir, *cp; 344 { 345 DIR *dirp; 346 struct direct *dp; 347 348 dirp = opendir(dir); 349 if (dirp == NULL) 350 return; 351 while ((dp = readdir(dirp)) != NULL) { 352 if (itsit(cp, dp->d_name)) { 353 count++; 354 if (print) 355 printf(" %s/%s", dir, dp->d_name); 356 } 357 } 358 closedir(dirp); 359 } 360 361 itsit(cp, dp) 362 register char *cp, *dp; 363 { 364 register int i = strlen(dp); 365 366 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 367 return (1); 368 while (*cp && *dp && *cp == *dp) 369 cp++, dp++, i--; 370 if (*cp == 0 && *dp == 0) 371 return (1); 372 while (isdigit(*dp)) 373 dp++; 374 if (*cp == 0 && *dp++ == '.') { 375 --i; 376 while (i > 0 && *dp) 377 if (--i, *dp++ == '.') 378 return (*dp++ == 'C' && *dp++ == 0); 379 return (1); 380 } 381 return (0); 382 } 383