|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.