/* Copyright (c) 1979 Regents of the University of California */ #include <sys/types.h> #include <stdio.h> #include <ctype.h> #include <sys/dir.h> static char *bindirs[] = { "/etc", "/bin", "/usr/bin", "/usr/new", "/usr/games", 0 }; static char *mandirs[] = { "man1", "man2", "man3", "man4", "man5", "man6", "man7", "man8", "mann", "127local", 0 }; static char *srcdirs[] = { "cmd", "libc/gen", "libc/stdio", "games", "/usr/ucb/src/cmd", "/usr/ucb/src/new", "/usr/ucb/src/libc/gen", "/usr/ucb/src/libc/stdio", 0 }; char sflag = 1; char bflag = 1; char mflag = 1; char **Sflag; int Scnt; char **Bflag; int Bcnt; char **Mflag; int Mcnt; char uflag; /* * whereis name * look for source, documentation and binaries */ main(argc, argv) int argc; char *argv[]; { #ifdef CORY if (getuid() == 0) nice(-20); if (((getuid() >> 8) & 0377) > 10) setuid(getuid()); #endif argc--, argv++; if (argc == 0) { usage: fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n"); exit(1); } do if (argv[0][0] == '-') { register char *cp = argv[0] + 1; while (*cp) switch (*cp++) { case 'f': break; case 'S': getlist(&argc, &argv, &Sflag, &Scnt); break; case 'B': getlist(&argc, &argv, &Bflag, &Bcnt); break; case 'M': getlist(&argc, &argv, &Mflag, &Mcnt); break; case 's': zerof(); sflag++; continue; case 'u': uflag++; continue; case 'b': zerof(); bflag++; continue; case 'm': zerof(); mflag++; continue; default: goto usage; } argv++; } else lookup(*argv++); while (--argc > 0); } getlist(argcp, argvp, flagp, cntp) char ***argvp; int *argcp; char ***flagp; int *cntp; { (*argvp)++; *flagp = *argvp; *cntp = 0; for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--) (*cntp)++, (*argvp)++; (*argcp)++; (*argvp)--; } zerof() { if (sflag && bflag && mflag) sflag = bflag = mflag = 0; } int count; int print; lookup(cp) register char *cp; { register char *dp; for (dp = cp; *dp; dp++) continue; for (; dp > cp; dp--) { if (*dp == '.') { *dp = 0; break; } } for (dp = cp; *dp; dp++) if (*dp == '/') cp = dp + 1; if (uflag) { print = 0; count = 0; } else print = 1; again: if (print) printf("%s:", cp); if (sflag) { looksrc(cp); if (uflag && print == 0 && count != 1) { print = 1; goto again; } } count = 0; if (bflag) { lookbin(cp); if (uflag && print == 0 && count != 1) { print = 1; goto again; } } count = 0; if (mflag) { lookman(cp); if (uflag && print == 0 && count != 1) { print = 1; goto again; } } if (print) printf("\n"); } looksrc(cp) char *cp; { if (Sflag == 0) { chdir("/usr/src"); find(srcdirs, cp); } else findv(Sflag, Scnt, cp); } lookbin(cp) char *cp; { if (Bflag == 0) find(bindirs, cp); else findv(Bflag, Bcnt, cp); } lookman(cp) char *cp; { if (Mflag == 0) { chdir("/usr/man"); find(mandirs, cp); } else findv(Mflag, Mcnt, cp); } findv(dirv, dirc, cp) char **dirv; int dirc; char *cp; { while (dirc > 0) findin(*dirv++, cp), dirc--; } find(dirs, cp) char **dirs; char *cp; { while (*dirs) findin(*dirs++, cp); } findin(dir, cp) char *dir, *cp; { register FILE *d; struct direct direct; d = fopen(dir, "r"); if (d == NULL) return; while (fread(&direct, sizeof direct, 1, d) == 1) { if (direct.d_ino == 0) continue; if (itsit(cp, direct.d_name)) { count++; if (print) printf(" %s/%.14s", dir, direct.d_name); } } fclose(d); } itsit(cp, dp) register char *cp, *dp; { register int i = 14; if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2)) return (1); while (*cp && *dp && *cp == *dp) cp++, dp++, i--; if (*cp == 0 && *dp == 0) return (1); while (isdigit(*dp)) dp++; if (*cp == 0 && *dp++ == '.') { --i; while (i > 0 && *dp) if (--i, *dp++ == '.') return (*dp++ == 'P' && *dp++ == 0); return (1); } return (0); }