|
|
1.1 ! root 1: /* ! 2: * A shell. ! 3: * Glob interpretation. ! 4: */ ! 5: #include "sh.h" ! 6: ! 7: #include <sys/types.h> ! 8: #include <sys/stat.h> ! 9: #include <dirent.h> ! 10: ! 11: #define DIRSIZ 14 ! 12: ! 13: struct nmlst { ! 14: struct nmlst * g_next; ! 15: char * g_name; ! 16: }; ! 17: ! 18: char *dirname = NULL; ! 19: int pref = 0; ! 20: ! 21: struct nmlst *newnm(); ! 22: char *gany(); ! 23: int nmcmp(); ! 24: ! 25: /* ! 26: * Initial glob driver, set up initial directory name, pattern, and ! 27: * suffix; call glob2; sort the results. ! 28: */ ! 29: glob1(args) ! 30: char *args; ! 31: { ! 32: register char *patt; ! 33: register char *suff; ! 34: register int nsep; ! 35: int myargc; ! 36: ! 37: if (gany(args)==NULL) { ! 38: /* Nothing to match */ ! 39: strip(args); ! 40: newarg(args, 0); ! 41: } else { ! 42: if (dirname != NULL) ! 43: sfree (dirname); ! 44: dirname = salloc (DIRSIZ); ! 45: if (args [0] == '/') { ! 46: pref = 0; ! 47: strcpy (dirname, "/"); ! 48: patt = args + 1; ! 49: } else { ! 50: pref = 2; ! 51: strcpy (dirname, "./"); ! 52: patt = args; ! 53: } ! 54: ! 55: if ((suff = strchr (patt, '/')) != NULL) ! 56: for (nsep = 0; * suff == '/'; nsep += 1) ! 57: * suff ++ = '\0'; ! 58: else ! 59: nsep = 0; ! 60: myargc = nargc; ! 61: glob2 (patt, nsep, suff); ! 62: if (myargc != nargc) ! 63: qsort (& nargv [myargc], nargc - myargc, ! 64: sizeof (nargv [0]), nmcmp); ! 65: else { ! 66: /* No match */ ! 67: while (nsep -- > 0) ! 68: * -- suff = '/'; ! 69: strip (args); ! 70: newarg (args, 0); ! 71: } ! 72: } ! 73: } ! 74: ! 75: nmcmp(cpp1, cpp2) ! 76: char **cpp1, **cpp2; ! 77: { ! 78: return (strcmp(*cpp1, *cpp2)); ! 79: } ! 80: ! 81: glob2(patt, nsep, suff) ! 82: char *patt, *suff; ! 83: int nsep; ! 84: { ! 85: register struct nmlst *nmlst = NULL; ! 86: struct nmlst *np; ! 87: char *nsuff, *ndirname; ! 88: int nnsep, dirp; ! 89: DIR * dir; ! 90: ! 91: if (gany(patt)==NULL) { ! 92: nmlst = newnm (nmlst, patt); ! 93: strip (nmlst->g_name); ! 94: } else if ((dir = opendir (dirname)) != NULL) { ! 95: struct dirent * direntry; ! 96: ! 97: while ((direntry = readdir (dir)) != NULL) { ! 98: if (match (patt, direntry->d_name) && ! 99: (direntry->d_name [0] != '.' || patt [0] == '.')) { ! 100: nmlst = newnm(nmlst, direntry->d_name); ! 101: } ! 102: } ! 103: closedir (dir); ! 104: } ! 105: ! 106: if (nmlst != NULL) { ! 107: ndirname = salloc (strlen (dirname) + DIRSIZ + nsep + 1); ! 108: strcpy (ndirname, dirname); ! 109: sfree (dirname); ! 110: dirname = ndirname; ! 111: dirp = strlen (dirname); ! 112: if ((nsuff = suff) != NULL && ! 113: (nsuff = strchr (nsuff, '/')) != NULL) ! 114: for (nnsep = 0; * nsuff == '/'; nnsep += 1) ! 115: * nsuff ++ = '\0'; ! 116: else ! 117: nnsep = 0; ! 118: while (nmlst != NULL) { ! 119: char * name; ! 120: name = dirname + dirp; ! 121: strcpy (name, nmlst->g_name); ! 122: nmlst = (np = nmlst)->g_next; ! 123: sfree (np); ! 124: mksep (name, nsep); ! 125: if (suff != NULL) ! 126: glob2 (suff, nnsep, nsuff); ! 127: else ! 128: newarg (dirname + pref, 1); ! 129: } ! 130: while (nnsep -- > 0) ! 131: * -- nsuff = '/'; ! 132: dirname [dirp] = '\0'; ! 133: } ! 134: } ! 135: ! 136: /* ! 137: * See if a pattern matches a string. ! 138: * '\' escapes the next character. ! 139: */ ! 140: match(pp, sp) ! 141: register char *pp; ! 142: register char *sp; ! 143: { ! 144: int c2; ! 145: register int c1; ! 146: int notflag; ! 147: ! 148: while ((c1=*pp++)) { ! 149: switch (c1) { ! 150: case '?': ! 151: if (*sp++) ! 152: continue; ! 153: return (0); ! 154: case '*': ! 155: do { ! 156: if (match(pp, sp)) ! 157: return (1); ! 158: } while (*sp++); ! 159: return (0); ! 160: case '[': ! 161: if ((c2=*sp++) == '\0') ! 162: return (0); ! 163: if ((notflag = * pp == '!') != 0) ! 164: pp ++; ! 165: for (;;) { ! 166: if ((c1=*pp++) == '\0') ! 167: return 0; ! 168: if (c1 == ']') { ! 169: if (notflag) { ! 170: pp --; ! 171: break; ! 172: } ! 173: return 0; ! 174: } ! 175: if (c1 == '\\' && (c1=*pp++) == '\0') ! 176: return 0; ! 177: if (c1 == c2) { ! 178: if (notflag) ! 179: return 0; ! 180: break; ! 181: } ! 182: if (*pp == '-') { ! 183: pp += 1; ! 184: if (c2 < c1) ! 185: continue; ! 186: if ((c1=*pp++) == '\0') ! 187: return (0); ! 188: if (c1 == '\\' && (c1=*pp++) == '\0') ! 189: return (0); ! 190: if (c2 <= c1) { ! 191: if (notflag) ! 192: return 0; ! 193: break; ! 194: } ! 195: } ! 196: } ! 197: while ((c1 = *pp++) != ']') { ! 198: if (c1 == '\0') ! 199: return (0); ! 200: if (c1 == '\\' && *pp++ == '\0') ! 201: return (0); ! 202: } ! 203: continue; ! 204: case '\\': ! 205: if ((c1=*pp++) == '\0') ! 206: return (0); ! 207: /* fall through */ ! 208: default: ! 209: if (c1 == *sp++) ! 210: continue; ! 211: return (0); ! 212: } ! 213: } ! 214: return (*sp=='\0'); ! 215: } ! 216: ! 217: struct nmlst * ! 218: newnm(olst, name) ! 219: struct nmlst *olst; ! 220: char *name; ! 221: { ! 222: register struct nmlst *np; ! 223: register int n; ! 224: ! 225: n = strlen (name) + 1 + sizeof (* np); ! 226: np = (struct nmlst *) salloc (n); ! 227: np->g_next = olst; ! 228: np->g_name = (char *) (np + 1); ! 229: strcpy(np->g_name, name); ! 230: return (np); ! 231: } ! 232: ! 233: mksep(cp, ns) ! 234: register char *cp; ! 235: register int ns; ! 236: { ! 237: while (*cp != '\0') ! 238: cp += 1; ! 239: while (ns-- > 0) ! 240: *cp++ = '/'; ! 241: *cp = '\0'; ! 242: } ! 243: ! 244: newarg(p, f) ! 245: char *p; ! 246: { ! 247: struct stat s; ! 248: ! 249: if (f && stat(p, &s) < 0) ! 250: return; ! 251: nargc += 1; ! 252: nargv = addargl(nargv, duplstr(p, 0)); ! 253: } ! 254: ! 255: /* ! 256: * Returns the location of the next unescaped glob character. ! 257: */ ! 258: char * ! 259: gany(s) ! 260: register char *s; ! 261: { ! 262: register int c; ! 263: ! 264: while (*s) ! 265: if ((c=*s++) == '\\') ! 266: if (*s++ == '\0') ! 267: return (NULL); ! 268: else ! 269: continue; ! 270: else if (c == '*' || c == '?' || c == '[') ! 271: return (--s); ! 272: return (NULL); ! 273: } ! 274: ! 275: /* ! 276: * get rid of the glob escapes. ! 277: */ ! 278: strip(s) ! 279: register char *s; ! 280: { ! 281: register char *p; ! 282: ! 283: p = s; ! 284: while (*s) ! 285: if ((*p = *s++) == '\\') ! 286: if (*p++ = *s++) ! 287: continue; ! 288: else ! 289: break; ! 290: else ! 291: p++; ! 292: *p = *s; ! 293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.