1 /* 2 * Copyright 1990 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 1980 Regents of the University of California. 8 * All rights reserved. The Berkeley software License Agreement 9 * specifies the terms and conditions for redistribution. 10 */ 11 12 #include <sys/param.h> 13 #include <dirent.h> 14 #include <stdio.h> 15 #include <ctype.h> 16 17 static char *bindirs[] = { 18 "/etc", 19 "/sbin", 20 "/usr/bin", 21 "/usr/ccs/bin", 22 "/usr/ccs/lib", 23 "/usr/lang", 24 "/usr/lbin", 25 "/usr/lib", 26 "/usr/sbin", 27 "/usr/ucb", 28 "/usr/ucblib", 29 "/usr/ucbinclude", 30 "/usr/games", 31 "/usr/local", 32 "/usr/local/bin", 33 "/usr/new", 34 "/usr/old", 35 "/usr/hosts", 36 "/usr/include", 37 "/usr/etc", 38 0 39 }; 40 static char *mandirs[] = { 41 "/usr/man/man1", 42 "/usr/man/man1b", 43 "/usr/man/man1c", 44 "/usr/man/man1f", 45 "/usr/man/man1m", 46 "/usr/man/man1s", 47 "/usr/man/man2", 48 "/usr/man/man3", 49 "/usr/man/man3b", 50 "/usr/man/man3c", 51 "/usr/man/man3e", 52 "/usr/man/man3g", 53 "/usr/man/man3j", 54 "/usr/man/man3k", 55 "/usr/man/man3l", 56 "/usr/man/man3m", 57 "/usr/man/man3n", 58 "/usr/man/man3s", 59 "/usr/man/man3w", 60 "/usr/man/man3x", 61 "/usr/man/man3x11", 62 "/usr/man/man3xt", 63 "/usr/man/man4", 64 "/usr/man/man4b", 65 "/usr/man/man5", 66 "/usr/man/man6", 67 "/usr/man/man7", 68 "/usr/man/man7b", 69 "/usr/man/man8", 70 "/usr/man/man9e", 71 "/usr/man/man9f", 72 "/usr/man/man9s", 73 "/usr/man/manl", 74 "/usr/man/mann", 75 "/usr/man/mano", 76 0 77 }; 78 static char *srcdirs[] = { 79 "/usr/src/cmd", 80 "/usr/src/head", 81 "/usr/src/lib", 82 "/usr/src/lib/libc", 83 "/usr/src/lib/libc/port", 84 "/usr/src/lib/libc/port/gen", 85 "/usr/src/lib/libc/port/print", 86 "/usr/src/lib/libc/port/stdio", 87 "/usr/src/lib/libc/port/sys", 88 "/usr/src/lib/libc/sparc", 89 "/usr/src/lib/libc/sparc/gen", 90 "/usr/src/lib/libc/sparc/sys", 91 "/usr/src/ucbcmd", 92 "/usr/src/ucblib", 93 "/usr/src/ucbinclude", 94 "/usr/src/uts", 95 "/usr/src/uts/common", 96 "/usr/src/uts/sun", 97 "/usr/src/uts/sun4", 98 "/usr/src/uts/sun4c", 99 "/usr/src/uts/sparc", 100 "/usr/src/local", 101 "/usr/src/new", 102 "/usr/src/old", 103 0 104 }; 105 106 char sflag = 1; 107 char bflag = 1; 108 char mflag = 1; 109 char **Sflag; 110 int Scnt; 111 char **Bflag; 112 int Bcnt; 113 char **Mflag; 114 int Mcnt; 115 char uflag; 116 117 void getlist(int *, char ***, char ***, int *); 118 void zerof(void); 119 void lookup(char *); 120 void looksrc(char *); 121 void lookbin(char *); 122 void lookman(char *); 123 void findv(char **, int, char *); 124 void find(char **, char *); 125 void findin(char *, char *); 126 127 /* 128 * whereis name 129 * look for source, documentation and binaries 130 */ 131 int 132 main(int argc, char *argv[]) 133 { 134 135 argc--, argv++; 136 if (argc == 0) { 137 usage: 138 fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] " 139 "name...\n"); 140 exit(1); 141 } 142 do 143 if (argv[0][0] == '-') { 144 char *cp = argv[0] + 1; 145 while (*cp) { 146 147 switch (*cp++) { 148 149 case 'f': 150 break; 151 152 case 'S': 153 getlist(&argc, &argv, &Sflag, &Scnt); 154 break; 155 156 case 'B': 157 getlist(&argc, &argv, &Bflag, &Bcnt); 158 break; 159 160 case 'M': 161 getlist(&argc, &argv, &Mflag, &Mcnt); 162 break; 163 164 case 's': 165 zerof(); 166 sflag++; 167 continue; 168 169 case 'u': 170 uflag++; 171 continue; 172 173 case 'b': 174 zerof(); 175 bflag++; 176 continue; 177 178 case 'm': 179 zerof(); 180 mflag++; 181 continue; 182 183 default: 184 goto usage; 185 } 186 } 187 argv++; 188 } else 189 lookup(*argv++); 190 while (--argc > 0); 191 return (0); 192 } 193 194 void 195 getlist(int *argcp, char ***argvp, char ***flagp, int *cntp) 196 { 197 198 (*argvp)++; 199 *flagp = *argvp; 200 *cntp = 0; 201 for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) 202 (*cntp)++, (*argvp)++; 203 (*argcp)++; 204 (*argvp)--; 205 } 206 207 void 208 zerof(void) 209 { 210 211 if (sflag && bflag && mflag) 212 sflag = bflag = mflag = 0; 213 } 214 int count; 215 int print; 216 217 void 218 lookup(char *cp) 219 { 220 char *dp; 221 222 for (dp = cp; *dp; dp++) 223 continue; 224 for (; dp > cp; dp--) { 225 if (*dp == '.') { 226 *dp = 0; 227 break; 228 } 229 } 230 for (dp = cp; *dp; dp++) 231 if (*dp == '/') 232 cp = dp + 1; 233 if (uflag) { 234 print = 0; 235 count = 0; 236 } else 237 print = 1; 238 again: 239 if (print) 240 printf("%s:", cp); 241 if (sflag) { 242 looksrc(cp); 243 if (uflag && print == 0 && count != 1) { 244 print = 1; 245 goto again; 246 } 247 } 248 count = 0; 249 if (bflag) { 250 lookbin(cp); 251 if (uflag && print == 0 && count != 1) { 252 print = 1; 253 goto again; 254 } 255 } 256 count = 0; 257 if (mflag) { 258 lookman(cp); 259 if (uflag && print == 0 && count != 1) { 260 print = 1; 261 goto again; 262 } 263 } 264 if (print) 265 printf("\n"); 266 } 267 268 void 269 looksrc(char *cp) 270 { 271 if (Sflag == 0) { 272 find(srcdirs, cp); 273 } else 274 findv(Sflag, Scnt, cp); 275 } 276 277 void 278 lookbin(char *cp) 279 { 280 if (Bflag == 0) 281 find(bindirs, cp); 282 else 283 findv(Bflag, Bcnt, cp); 284 } 285 286 void 287 lookman(char *cp) 288 { 289 if (Mflag == 0) { 290 find(mandirs, cp); 291 } else 292 findv(Mflag, Mcnt, cp); 293 } 294 295 void 296 findv(char **dirv, int dirc, char *cp) 297 { 298 299 while (dirc > 0) 300 findin(*dirv++, cp), dirc--; 301 } 302 303 void 304 find(char **dirs, char *cp) 305 { 306 307 while (*dirs) 308 findin(*dirs++, cp); 309 } 310 311 void 312 findin(char *dir, char *cp) 313 { 314 DIR *dirp; 315 struct dirent *dp; 316 317 dirp = opendir(dir); 318 if (dirp == NULL) 319 return; 320 while ((dp = readdir(dirp)) != NULL) { 321 if (itsit(cp, dp->d_name)) { 322 count++; 323 if (print) 324 printf(" %s/%s", dir, dp->d_name); 325 } 326 } 327 closedir(dirp); 328 } 329 330 int 331 itsit(char *cp, char *dp) 332 { 333 int i = strlen(dp); 334 335 if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) 336 return (1); 337 while (*cp && *dp && *cp == *dp) 338 cp++, dp++, i--; 339 if (*cp == 0 && *dp == 0) 340 return (1); 341 while (isdigit(*dp)) 342 dp++; 343 if (*cp == 0 && *dp++ == '.') { 344 --i; 345 while (i > 0 && *dp) 346 if (--i, *dp++ == '.') 347 return (*dp++ == 'C' && *dp++ == 0); 348 return (1); 349 } 350 return (0); 351 } 352