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