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