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