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/gnu/usr.bin", 103 "/usr/src/usr.sbin", 104 "/usr/src/usr.ucb", 105 "/usr/src/usr.new", 106 "/usr/src/lib", 107 "/usr/src/gnu/lib", 108 "/usr/src/libexec", 109 "/usr/src/gnu/libexec", 110 "/usr/src/libdata", 111 "/usr/src/share", 112 "/usr/src/contrib", 113 "/usr/src/athena", 114 "/usr/src/devel", 115 "/usr/src/games", 116 "/usr/src/gnu/games", 117 "/usr/src/local", 118 "/usr/src/man", 119 "/usr/src/root", 120 "/usr/src/old", 121 "/usr/src/include", 122 /* still need libs */ 123 #ifdef notdef /* before reorg */ 124 "/usr/src/bin", 125 "/usr/src/usr.bin", 126 "/usr/src/etc", 127 "/usr/src/ucb", 128 "/usr/src/games", 129 "/usr/src/usr.lib", 130 "/usr/src/lib", 131 "/usr/src/local", 132 "/usr/src/new", 133 "/usr/src/old", 134 "/usr/src/include", 135 "/usr/src/lib/libc/gen", 136 "/usr/src/lib/libc/stdio", 137 "/usr/src/lib/libc/sys", 138 "/usr/src/lib/libc/net/common", 139 "/usr/src/lib/libc/net/inet", 140 "/usr/src/lib/libc/net/misc", 141 "/usr/src/ucb/pascal", 142 "/usr/src/ucb/pascal/utilities", 143 "/usr/src/undoc", 144 #endif 145 0 146 }; 147 148 char sflag = 1; 149 char bflag = 1; 150 char mflag = 1; 151 char **Sflag; 152 int Scnt; 153 char **Bflag; 154 int Bcnt; 155 char **Mflag; 156 int Mcnt; 157 char uflag; 158 /* 159 * whereis name 160 * look for source, documentation and binaries 161 */ 162 main(argc, argv) 163 int argc; 164 char *argv[]; 165 { 166 167 argc--, argv++; 168 if (argc == 0) { 169 usage: 170 fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); 171 exit(1); 172 } 173 do 174 if (argv[0][0] == '-') { 175 register char *cp = argv[0] + 1; 176 while (*cp) switch (*cp++) { 177 178 case 'f': 179 break; 180 181 case 'S': 182 getlist(&argc, &argv, &Sflag, &Scnt); 183 break; 184 185 case 'B': 186 getlist(&argc, &argv, &Bflag, &Bcnt); 187 break; 188 189 case 'M': 190 getlist(&argc, &argv, &Mflag, &Mcnt); 191 break; 192 193 case 's': 194 zerof(); 195 sflag++; 196 continue; 197 198 case 'u': 199 uflag++; 200 continue; 201 202 case 'b': 203 zerof(); 204 bflag++; 205 continue; 206 207 case 'm': 208 zerof(); 209 mflag++; 210 continue; 211 212 default: 213 goto usage; 214 } 215 argv++; 216 } else 217 lookup(*argv++); 218 while (--argc > 0); 219 exit(0); 220 } 221 222 getlist(argcp, argvp, flagp, cntp) 223 char ***argvp; 224 int *argcp; 225 char ***flagp; 226 int *cntp; 227 { 228 229 (*argvp)++; 230 *flagp = *argvp; 231 *cntp = 0; 232 for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 233 (*cntp)++, (*argvp)++; 234 (*argcp)++; 235 (*argvp)--; 236 } 237 238 239 zerof() 240 { 241 242 if (sflag && bflag && mflag) 243 sflag = bflag = mflag = 0; 244 } 245 int count; 246 int print; 247 248 249 lookup(cp) 250 register char *cp; 251 { 252 register char *dp; 253 254 for (dp = cp; *dp; dp++) 255 continue; 256 for (; dp > cp; dp--) { 257 if (*dp == '.') { 258 *dp = 0; 259 break; 260 } 261 } 262 for (dp = cp; *dp; dp++) 263 if (*dp == '/') 264 cp = dp + 1; 265 if (uflag) { 266 print = 0; 267 count = 0; 268 } else 269 print = 1; 270 again: 271 if (print) 272 printf("%s:", cp); 273 if (sflag) { 274 looksrc(cp); 275 if (uflag && print == 0 && count != 1) { 276 print = 1; 277 goto again; 278 } 279 } 280 count = 0; 281 if (bflag) { 282 lookbin(cp); 283 if (uflag && print == 0 && count != 1) { 284 print = 1; 285 goto again; 286 } 287 } 288 count = 0; 289 if (mflag) { 290 lookman(cp); 291 if (uflag && print == 0 && count != 1) { 292 print = 1; 293 goto again; 294 } 295 } 296 if (print) 297 printf("\n"); 298 } 299 300 looksrc(cp) 301 char *cp; 302 { 303 if (Sflag == 0) { 304 find(srcdirs, cp); 305 } else 306 findv(Sflag, Scnt, cp); 307 } 308 309 lookbin(cp) 310 char *cp; 311 { 312 if (Bflag == 0) 313 find(bindirs, cp); 314 else 315 findv(Bflag, Bcnt, cp); 316 } 317 318 lookman(cp) 319 char *cp; 320 { 321 if (Mflag == 0) { 322 find(mandirs, cp); 323 } else 324 findv(Mflag, Mcnt, cp); 325 } 326 327 findv(dirv, dirc, cp) 328 char **dirv; 329 int dirc; 330 char *cp; 331 { 332 333 while (dirc > 0) 334 findin(*dirv++, cp), dirc--; 335 } 336 337 find(dirs, cp) 338 char **dirs; 339 char *cp; 340 { 341 342 while (*dirs) 343 findin(*dirs++, cp); 344 } 345 346 findin(dir, cp) 347 char *dir, *cp; 348 { 349 DIR *dirp; 350 struct direct *dp; 351 352 dirp = opendir(dir); 353 if (dirp == NULL) 354 return; 355 while ((dp = readdir(dirp)) != NULL) { 356 if (itsit(cp, dp->d_name)) { 357 count++; 358 if (print) 359 printf(" %s/%s", dir, dp->d_name); 360 } 361 } 362 closedir(dirp); 363 } 364 365 itsit(cp, dp) 366 register char *cp, *dp; 367 { 368 register int i = strlen(dp); 369 370 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 371 return (1); 372 while (*cp && *dp && *cp == *dp) 373 cp++, dp++, i--; 374 if (*cp == 0 && *dp == 0) 375 return (1); 376 while (isdigit(*dp)) 377 dp++; 378 if (*cp == 0 && *dp++ == '.') { 379 --i; 380 while (i > 0 && *dp) 381 if (--i, *dp++ == '.') 382 return (*dp++ == 'C' && *dp++ == 0); 383 return (1); 384 } 385 return (0); 386 } 387