Annotation of coherent/b/bin/srcpath.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Expand $SRCPATH and apply it to each argument printing the
                      3:  * full path of the result.
                      4:  * Allow pattern type arguments for example.
                      5:  * srcpath "*.[ch]"
                      6:  * Will find all .c and .h files on $SRCPATH eliminating duplicates.
                      7:  * .: will automatically be prepended to $SRCPATH so that files
                      8:  * in the current directory have preference.
                      9:  * 
                     10:  * The first arguments may be -p pathlist for example
                     11:  * srcpath -p ".:/usr/src/cmd" "*.c"
                     12:  * Note: . is not automatically prepended to this list.
                     13:  *
                     14:  * The -a option disables shadowing. Normally if a file is found
                     15:  * in two directorys on the path only the first if printed.
                     16:  * -a causes it to be printed twice.
                     17:  *
                     18:  * Normally srcpath silently bypasses directorys and matching files
                     19:  * on which it has no read permission. The -w option causes it to
                     20:  * print a warning message on stderr.
                     21:  */
                     22: #include <stdio.h>
                     23: #include <sys/types.h>
                     24: #include <sys/dir.h>
                     25: #include <path.h>
                     26: #include <dirent.h>
                     27: #include <access.h>
                     28: 
                     29: struct savepath {
                     30:        char name[DIRSIZ + 1];  /* zero terminated directory name */
                     31:        char *path;             /* pointer to path or NULL */
                     32: };
                     33: 
                     34: static struct savepath *found = NULL; 
                     35: static int ents;
                     36: static int allsw, warnsw;
                     37: 
                     38: /*
                     39:  * Print out of space message and die.
                     40:  */
                     41: static void
                     42: outSpace()
                     43: {
                     44:        fprintf(stderr, "srcpath: out of space");
                     45:        exit(1);
                     46: }
                     47: 
                     48: /*
                     49:  * Print cannot read warning if warnsw is on.
                     50:  */
                     51: static void
                     52: noRead(name)
                     53: char *name;
                     54: {
                     55:        if (warnsw)
                     56:                fprintf(stderr, "srcpath: cannot read '%s'\n", name);
                     57: }
                     58: 
                     59: /*
                     60:  * Check if the directory entry matches any argv entries.
                     61:  */
                     62: static void
                     63: checkit(d_name, argv, path)
                     64: char *d_name;
                     65: register char *argv[];
                     66: char *path;
                     67: {
                     68:        char work[DIRSIZ + 1];  /* zero terminated version of dent->d_name */
                     69:        char name[MAXPATH];
                     70:        static int nents;       /* number of entries allowed */
                     71: 
                     72:        memcpy(work, d_name, DIRSIZ);
                     73:        work[DIRSIZ] = '\0';
                     74: 
                     75:        for (;NULL != *argv; argv++) {
                     76:                /* the filename must match the arguement */
                     77:                if (!pnmatch(work, *argv, 0))
                     78:                        continue;
                     79: 
                     80:                /* we must have read permission */
                     81:                sprintf(name, "%s/%s", path, work);
                     82:                if(access(name, AREAD)) {
                     83:                        noRead(name);
                     84:                        continue;
                     85:                }
                     86: 
                     87:                /* realloc() more space if we've run out. */
                     88:                if(ents >= nents) {
                     89:                        extern char *realloc();
                     90: 
                     91:                        nents += 20;
                     92:                        found = realloc(found, nents * sizeof(*found));
                     93:                        if(NULL == found)
                     94:                                outSpace();
                     95:                }
                     96: 
                     97:                /* save name and pointer to path */
                     98:                strcpy(found[ents].name, work);
                     99:                found[ents++].path = path;
                    100:        }
                    101: }
                    102: 
                    103: /*
                    104:  * Compare two directory entrys by name then location of the path pointer.
                    105:  */
                    106: static int
                    107: compr(d1, d2)
                    108: register struct savepath *d1, *d2;
                    109: {
                    110:        register int i;
                    111: 
                    112:        return ((i = strcmp(d1->name, d2->name)) ? i : (d1->path - d2->path));
                    113: }
                    114: 
                    115: main(argc, argv)
                    116: char *argv[];
                    117: {
                    118:        register char *p;
                    119:        char *end, *env, *dotenv;
                    120:        extern char *optarg, *getenv(), *strchr();
                    121:        extern int optind;
                    122:        int i, errflag;
                    123: 
                    124:        dotenv = NULL;
                    125:        allsw, errflag = 0;
                    126:        while ((i = getopt(argc, argv, "?awp:")) != EOF) {
                    127:                switch (i) {
                    128:                case 'a':
                    129:                        allsw = 1;      /* print all matches */
                    130:                        break;
                    131:                case 'w':
                    132:                        warnsw = 1;     /* warn of inaccessable files */
                    133:                        break;
                    134:                /* if args start -p pathlist use that pathlist not $SRCPATH */
                    135:                case 'p':
                    136:                        dotenv = optarg;
                    137:                        break;
                    138:                default:
                    139:                        errflag++;
                    140:                }
                    141:        }
                    142:        argv += optind; /* point argv at first file name */
                    143:        if (errflag) {
                    144:                fprintf(stderr,
                    145:                        "usage: srcpath [-aw] [-p path] file ...\n");
                    146:                exit(1);
                    147:        }
                    148: 
                    149:        if (NULL == dotenv) {            /* no use of -p */
                    150:                if (NULL == (env = getenv("SRCPATH"))) {
                    151:                        if (NULL == (dotenv = malloc(2)))
                    152:                                outSpace();
                    153:                        strcpy(dotenv, ".");
                    154:                }
                    155:                else {
                    156:                        /* prepend .: to $SRCPATH */
                    157:                        if (NULL == (dotenv = malloc(strlen(env) + 3)))
                    158:                                outSpace();
                    159:                        sprintf(dotenv, ".%c%s", LISTSEP, env);
                    160:                }
                    161:        }
                    162: 
                    163:        /* replace LISTSEP with '\0' and locate the end */
                    164:        for (end = dotenv; *end; end++)
                    165:                if (LISTSEP == *end)
                    166:                        *end = '\0';
                    167:        
                    168:        /* for each path name */
                    169:        for (p = dotenv; p < end; p = strchr(p, '\0') + 1) {
                    170:                DIR *dirp;
                    171:                struct dirent *dp;
                    172: 
                    173:                /* ignore bad path entries */
                    174:                if (access(p, ALIST) || (NULL == (dirp = opendir(p)))) {
                    175:                        noRead(p);
                    176:                        continue;
                    177:                }
                    178: 
                    179:                /* for each directory entry */
                    180:                while (NULL != (dp = readdir(dirp)))
                    181:                        checkit(dp->d_name, argv, p);
                    182: 
                    183:                closedir(dirp);
                    184:        }
                    185: 
                    186:        /* sort by name then position on pathlist */
                    187:        qsort(found, ents, sizeof(struct savepath), compr);
                    188: 
                    189:        /* eliminate duplicate names and print the remainder. */
                    190:        for (i = 1; i <= ents; i++) {
                    191:                if (!allsw && !strcmp(found[i - 1].name, found[i].name))
                    192:                        found[i].path = NULL;
                    193:                if (NULL != found[i - 1].path)
                    194:                        printf("%s/%s\n", found[i - 1].path, found[i - 1].name);
                    195:        }
                    196:        exit(0);
                    197: }

unix.superglobalmegacorp.com

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