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