Annotation of coherent/d/bin/which.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * locate a program file along the user's PATH.
        !             3:  * try to mimic output of the BSD version.
        !             4:  */
        !             5: #include <stdio.h>
        !             6: #include <sys/stat.h>
        !             7: #include <access.h>
        !             8: 
        !             9: char   *getenv();
        !            10: char   *index();
        !            11: char   **parsepath();          /* parse PATH into argv-like structure */
        !            12: void   fatal();                /* display error message and die */
        !            13: void   usage();                /* display usage message and die */
        !            14: char   *calloc();
        !            15: char   *index();
        !            16: 
        !            17: #define        TRUE            (0 == 0)
        !            18: #define        FALSE           (0 != 0)
        !            19: #define        EXEC_BITS       (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6))
        !            20: 
        !            21: main(argc, argv)
        !            22: int    argc;
        !            23: char   *argv[];
        !            24: {
        !            25:        char    *pathp;                         /* pointer to PATH string */
        !            26:        char    **pathpp;                       /* pointer to path entries */
        !            27:        char    **pathlist;                     /* pointer to path list */
        !            28:        static  char    pathbuf[BUFSIZ];        /* expanded file names */
        !            29:        static  char    path[BUFSIZ];           /* saved copy for error msgs */
        !            30: 
        !            31:        if ((pathp = getenv("PATH")) == NULL)
        !            32:                fatal("PATH not found in environment");
        !            33:        strcpy(path, pathp);
        !            34:        if (--argc < 1)
        !            35:                usage();
        !            36:        pathlist = parsepath(pathp);
        !            37: 
        !            38:        for (++argv; argc-- > 0; ++argv) {
        !            39:                pathpp = pathlist;
        !            40:                for ( ; *pathpp != NULL; ++pathpp) {
        !            41:                        if (**pathpp != '\0') {
        !            42:                                strcpy(pathbuf, *pathpp);
        !            43:                                strcat(pathbuf, "/");
        !            44:                                strcat(pathbuf, *argv);
        !            45:                        } else
        !            46:                                strcpy(pathbuf, *argv);
        !            47:                        if (is_exec(pathbuf)) {
        !            48:                                puts(pathbuf);
        !            49:                                break;
        !            50:                        }
        !            51:                }
        !            52:                if (*pathpp == NULL)
        !            53:                        if (index(*argv, '/') != NULL)
        !            54:                                printf("%s not found\n", *argv);
        !            55:                        else
        !            56:                                printf("no %s in %s\n", *argv, path);
        !            57:        }
        !            58:        exit(0);
        !            59: }
        !            60: 
        !            61: /*
        !            62:  * check to see if the given name is executable.
        !            63:  * this isn't as trivial as it may seem since access() says
        !            64:  * that root (UID 0) can execute anything, even if the
        !            65:  * execute mode bits are not set.
        !            66:  */
        !            67: is_exec(name)
        !            68: char   *name;
        !            69: {
        !            70:        static  struct  stat    statbuf;
        !            71: 
        !            72:        if (access(name, AEXEC) != 0)
        !            73:                return FALSE;
        !            74:        if (stat(name, &statbuf) == -1) {
        !            75:                fprintf(stderr, "%s: Unable to stat\n", name);
        !            76:                return FALSE;
        !            77:        }
        !            78:        if ((statbuf.st_mode & S_IFMT) != S_IFREG)
        !            79:                return FALSE;
        !            80:        return (getuid() != 0 || (statbuf.st_mode & EXEC_BITS));
        !            81: }
        !            82: 
        !            83: /*
        !            84:  * parse a path of the form dir1:dir2:dir3 into an array of pointers to
        !            85:  * the individual directory entries. Note that this null terminates each
        !            86:  * directory entry by replacing all ':' characters in "path" with NUL's. 
        !            87:  * take special care of leading and trailing ':' which imply the current
        !            88:  * directory.
        !            89:  */
        !            90: char   **
        !            91: parsepath(path)
        !            92: char   *path;
        !            93: {
        !            94:        register char   *cp;
        !            95:        register int    i = 1;
        !            96:        char    **patharray, **pp;
        !            97: 
        !            98:        for (cp = path; *cp != '\0'; )  /* calculate number of entries */
        !            99:                if (*cp++ == ':')
        !           100:                        ++i;
        !           101:        if ((patharray = (char **)calloc(i + 1, sizeof (char *))) == NULL)
        !           102:                fatal("Out of memory for PATH list");
        !           103:        for (cp = path, pp = patharray; *cp != '\0' || pp == patharray; ) {
        !           104:                *pp++ = cp;
        !           105:                while (*cp != '\0') {
        !           106:                        if (*cp == ':') {
        !           107:                                *cp++ = '\0';
        !           108:                                break;
        !           109:                        }
        !           110:                        ++cp;
        !           111:                }
        !           112:                if ((pp - patharray) < i)
        !           113:                        *pp = cp;
        !           114:        }
        !           115:        return (patharray);
        !           116: }
        !           117: 
        !           118: void
        !           119: usage()
        !           120: {
        !           121:        fatal("usage: which name ....");
        !           122: }
        !           123: 
        !           124: void
        !           125: fatal(info)
        !           126: char   *info;
        !           127: {
        !           128:        fprintf(stderr, "which: %r\n", &info);
        !           129:        exit(1);
        !           130: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.