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