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.3 (Berkeley) 03/10/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 "/etc", 35 "/bin", 36 "/usr/bin", 37 "/usr/games", 38 "/lib", 39 "/usr/ucb", 40 "/usr/lib", 41 "/usr/local", 42 "/usr/new", 43 "/usr/old", 44 "/usr/hosts", 45 "/usr/include", 46 0 47 }; 48 static char *mandirs[] = { 49 "/usr/man/man1", 50 "/usr/man/man2", 51 "/usr/man/man3", 52 "/usr/man/man4", 53 "/usr/man/man5", 54 "/usr/man/man6", 55 "/usr/man/man7", 56 "/usr/man/man8", 57 "/usr/man/manl", 58 "/usr/man/mann", 59 "/usr/man/mano", 60 0 61 }; 62 static char *srcdirs[] = { 63 "/usr/src/bin", 64 "/usr/src/usr.bin", 65 "/usr/src/etc", 66 "/usr/src/ucb", 67 "/usr/src/games", 68 "/usr/src/usr.lib", 69 "/usr/src/lib", 70 "/usr/src/local", 71 "/usr/src/new", 72 "/usr/src/old", 73 "/usr/src/include", 74 "/usr/src/lib/libc/gen", 75 "/usr/src/lib/libc/stdio", 76 "/usr/src/lib/libc/sys", 77 "/usr/src/lib/libc/net/common", 78 "/usr/src/lib/libc/net/inet", 79 "/usr/src/lib/libc/net/misc", 80 "/usr/src/ucb/pascal", 81 "/usr/src/ucb/pascal/utilities", 82 "/usr/src/undoc", 83 0 84 }; 85 86 char sflag = 1; 87 char bflag = 1; 88 char mflag = 1; 89 char **Sflag; 90 int Scnt; 91 char **Bflag; 92 int Bcnt; 93 char **Mflag; 94 int Mcnt; 95 char uflag; 96 /* 97 * whereis name 98 * look for source, documentation and binaries 99 */ 100 main(argc, argv) 101 int argc; 102 char *argv[]; 103 { 104 105 argc--, argv++; 106 if (argc == 0) { 107 usage: 108 fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); 109 exit(1); 110 } 111 do 112 if (argv[0][0] == '-') { 113 register char *cp = argv[0] + 1; 114 while (*cp) switch (*cp++) { 115 116 case 'f': 117 break; 118 119 case 'S': 120 getlist(&argc, &argv, &Sflag, &Scnt); 121 break; 122 123 case 'B': 124 getlist(&argc, &argv, &Bflag, &Bcnt); 125 break; 126 127 case 'M': 128 getlist(&argc, &argv, &Mflag, &Mcnt); 129 break; 130 131 case 's': 132 zerof(); 133 sflag++; 134 continue; 135 136 case 'u': 137 uflag++; 138 continue; 139 140 case 'b': 141 zerof(); 142 bflag++; 143 continue; 144 145 case 'm': 146 zerof(); 147 mflag++; 148 continue; 149 150 default: 151 goto usage; 152 } 153 argv++; 154 } else 155 lookup(*argv++); 156 while (--argc > 0); 157 exit(0); 158 } 159 160 getlist(argcp, argvp, flagp, cntp) 161 char ***argvp; 162 int *argcp; 163 char ***flagp; 164 int *cntp; 165 { 166 167 (*argvp)++; 168 *flagp = *argvp; 169 *cntp = 0; 170 for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 171 (*cntp)++, (*argvp)++; 172 (*argcp)++; 173 (*argvp)--; 174 } 175 176 177 zerof() 178 { 179 180 if (sflag && bflag && mflag) 181 sflag = bflag = mflag = 0; 182 } 183 int count; 184 int print; 185 186 187 lookup(cp) 188 register char *cp; 189 { 190 register char *dp; 191 192 for (dp = cp; *dp; dp++) 193 continue; 194 for (; dp > cp; dp--) { 195 if (*dp == '.') { 196 *dp = 0; 197 break; 198 } 199 } 200 for (dp = cp; *dp; dp++) 201 if (*dp == '/') 202 cp = dp + 1; 203 if (uflag) { 204 print = 0; 205 count = 0; 206 } else 207 print = 1; 208 again: 209 if (print) 210 printf("%s:", cp); 211 if (sflag) { 212 looksrc(cp); 213 if (uflag && print == 0 && count != 1) { 214 print = 1; 215 goto again; 216 } 217 } 218 count = 0; 219 if (bflag) { 220 lookbin(cp); 221 if (uflag && print == 0 && count != 1) { 222 print = 1; 223 goto again; 224 } 225 } 226 count = 0; 227 if (mflag) { 228 lookman(cp); 229 if (uflag && print == 0 && count != 1) { 230 print = 1; 231 goto again; 232 } 233 } 234 if (print) 235 printf("\n"); 236 } 237 238 looksrc(cp) 239 char *cp; 240 { 241 if (Sflag == 0) { 242 find(srcdirs, cp); 243 } else 244 findv(Sflag, Scnt, cp); 245 } 246 247 lookbin(cp) 248 char *cp; 249 { 250 if (Bflag == 0) 251 find(bindirs, cp); 252 else 253 findv(Bflag, Bcnt, cp); 254 } 255 256 lookman(cp) 257 char *cp; 258 { 259 if (Mflag == 0) { 260 find(mandirs, cp); 261 } else 262 findv(Mflag, Mcnt, cp); 263 } 264 265 findv(dirv, dirc, cp) 266 char **dirv; 267 int dirc; 268 char *cp; 269 { 270 271 while (dirc > 0) 272 findin(*dirv++, cp), dirc--; 273 } 274 275 find(dirs, cp) 276 char **dirs; 277 char *cp; 278 { 279 280 while (*dirs) 281 findin(*dirs++, cp); 282 } 283 284 findin(dir, cp) 285 char *dir, *cp; 286 { 287 DIR *dirp; 288 struct direct *dp; 289 290 dirp = opendir(dir); 291 if (dirp == NULL) 292 return; 293 while ((dp = readdir(dirp)) != NULL) { 294 if (itsit(cp, dp->d_name)) { 295 count++; 296 if (print) 297 printf(" %s/%s", dir, dp->d_name); 298 } 299 } 300 closedir(dirp); 301 } 302 303 itsit(cp, dp) 304 register char *cp, *dp; 305 { 306 register int i = strlen(dp); 307 308 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 309 return (1); 310 while (*cp && *dp && *cp == *dp) 311 cp++, dp++, i--; 312 if (*cp == 0 && *dp == 0) 313 return (1); 314 while (isdigit(*dp)) 315 dp++; 316 if (*cp == 0 && *dp++ == '.') { 317 --i; 318 while (i > 0 && *dp) 319 if (--i, *dp++ == '.') 320 return (*dp++ == 'C' && *dp++ == 0); 321 return (1); 322 } 323 return (0); 324 } 325