|
|
1.1 ! root 1: /* @(#)expand.c 1.4 */ ! 2: /* ! 3: * UNIX shell ! 4: * ! 5: * Bell Telephone Laboratories ! 6: * ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include <sys/types.h> ! 11: #include <sys/stat.h> ! 12: #ifdef BSD4_2 ! 13: #include <sys/dir.h> ! 14: #else ! 15: #include <ndir.h> ! 16: #endif ! 17: ! 18: #ifdef BSD4_2 ! 19: #define DIRSIZE MAXNAMELEN ! 20: #else ! 21: #define DIRSIZE 14 ! 22: #endif ! 23: #ifndef MAXNAMELEN ! 24: #define MAXNAMELEN 255 ! 25: #endif ! 26: ! 27: ! 28: static char entry[DIRSIZE+1]; ! 29: ! 30: /* ! 31: * globals (file name generation) ! 32: * ! 33: * "*" in params matches r.e ".*" ! 34: * "?" in params matches r.e. "." ! 35: * "[...]" in params matches character class ! 36: * "[...a-z...]" in params matches a through z. ! 37: * ! 38: */ ! 39: ! 40: static addg(); ! 41: ! 42: expand(as, rcnt) ! 43: char *as; ! 44: { ! 45: int count; ! 46: DIR *dirf; ! 47: struct direct *e; ! 48: BOOL dir = 0; ! 49: char *rescan = 0; ! 50: register char *s, *cs; ! 51: struct argnod *schain = gchain; ! 52: BOOL slash; ! 53: ! 54: if (trapnote & SIGSET) ! 55: return(0); ! 56: s = cs = as; ! 57: /* ! 58: * check for meta chars ! 59: */ ! 60: { ! 61: register BOOL open; ! 62: ! 63: slash = 0; ! 64: open = 0; ! 65: do ! 66: { ! 67: switch (*cs++) ! 68: { ! 69: case 0: ! 70: if (rcnt && slash) ! 71: break; ! 72: else ! 73: return(0); ! 74: ! 75: case '/': ! 76: slash++; ! 77: open = 0; ! 78: continue; ! 79: ! 80: case '[': ! 81: open++; ! 82: continue; ! 83: ! 84: case ']': ! 85: if (open == 0) ! 86: continue; ! 87: ! 88: case '?': ! 89: case '*': ! 90: if (rcnt > slash) ! 91: continue; ! 92: else ! 93: cs--; ! 94: break; ! 95: ! 96: ! 97: default: ! 98: continue; ! 99: } ! 100: break; ! 101: } while (TRUE); ! 102: } ! 103: ! 104: for (;;) ! 105: { ! 106: if (cs == s) ! 107: { ! 108: s = nullstr; ! 109: break; ! 110: } ! 111: else if (*--cs == '/') ! 112: { ! 113: *cs = 0; ! 114: if (s == cs) ! 115: s = "/"; ! 116: break; ! 117: } ! 118: } ! 119: ! 120: if ((dirf = opendir(*s ? s : ".")) != 0) ! 121: dir = TRUE; ! 122: ! 123: count = 0; ! 124: if (*cs == 0) ! 125: *cs++ = 0200; ! 126: ! 127: if(dir) ! 128: { ! 129: register char *rs; ! 130: ! 131: rs = cs; ! 132: do ! 133: { ! 134: if (*rs == '/') ! 135: { ! 136: rescan = rs; ! 137: *rs = 0; ! 138: gchain = 0; ! 139: } ! 140: } while (*rs++); ! 141: ! 142: while ((e = readdir(dirf)) && (trapnote & SIGSET) == 0) ! 143: { ! 144: *(movstrn(e->d_name, entry, DIRSIZE)) = 0; ! 145: if (entry[0] == '.' && *cs != '.') ! 146: { ! 147: if (entry[1] == 0) ! 148: continue; ! 149: if (entry[1] == '.' && entry[2] == 0) ! 150: continue; ! 151: } ! 152: ! 153: if (gmatch(entry, cs)) ! 154: { ! 155: addg(s, entry, rescan); ! 156: count++; ! 157: } ! 158: } ! 159: closedir(dirf); ! 160: ! 161: if (rescan) ! 162: { ! 163: register struct argnod *rchain; ! 164: ! 165: rchain = gchain; ! 166: gchain = schain; ! 167: if (count) ! 168: { ! 169: count = 0; ! 170: while (rchain) ! 171: { ! 172: count += expand(rchain->argval, slash + 1); ! 173: rchain = rchain->argnxt; ! 174: } ! 175: } ! 176: *rescan = '/'; ! 177: } ! 178: } ! 179: ! 180: { ! 181: register char c; ! 182: ! 183: s = as; ! 184: while (c = *s) ! 185: *s++ = (c & STRIP ? c : '/'); ! 186: } ! 187: return(count); ! 188: } ! 189: ! 190: ! 191: ! 192: gmatch(s, p) ! 193: register char *s, *p; ! 194: { ! 195: register int scc; ! 196: char c; ! 197: ! 198: if (scc = *s++) ! 199: { ! 200: if ((scc &= STRIP) == 0) ! 201: scc=0200; ! 202: } ! 203: switch (c = *p++) ! 204: { ! 205: case '[': ! 206: { ! 207: BOOL ok; ! 208: int lc; ! 209: int notflag = 0; ! 210: ! 211: ok = 0; ! 212: lc = 077777; ! 213: if (*p == '^') ! 214: { ! 215: notflag = 1; ! 216: p++; ! 217: } ! 218: while (c = *p++) ! 219: { ! 220: if (c == ']') ! 221: return(ok ? gmatch(s, p) : 0); ! 222: else if (c == MINUS) ! 223: { ! 224: if (notflag) ! 225: { ! 226: if (scc < lc || scc > *(p++)) ! 227: ok++; ! 228: else ! 229: return(0); ! 230: } ! 231: else ! 232: { ! 233: if (lc <= scc && scc <= (*p++)) ! 234: ok++; ! 235: } ! 236: } ! 237: else ! 238: { ! 239: lc = c & STRIP; ! 240: if (notflag) ! 241: { ! 242: if (scc && scc != lc) ! 243: ok++; ! 244: else ! 245: return(0); ! 246: } ! 247: else ! 248: { ! 249: if (scc == lc) ! 250: ok++; ! 251: } ! 252: } ! 253: } ! 254: return(0); ! 255: } ! 256: ! 257: default: ! 258: if ((c & STRIP) != scc) ! 259: return(0); ! 260: ! 261: case '?': ! 262: return(scc ? gmatch(s, p) : 0); ! 263: ! 264: case '*': ! 265: while (*p == '*') ! 266: p++; ! 267: ! 268: if (*p == 0) ! 269: return(1); ! 270: --s; ! 271: while (*s) ! 272: { ! 273: if (gmatch(s++, p)) ! 274: return(1); ! 275: } ! 276: return(0); ! 277: ! 278: case 0: ! 279: return(scc == 0); ! 280: } ! 281: } ! 282: ! 283: static ! 284: addg(as1, as2, as3) ! 285: char *as1, *as2, *as3; ! 286: { ! 287: register char *s1; ! 288: register int c; ! 289: ! 290: staktop = locstak() + BYTESPERWORD; ! 291: s1 = as1; ! 292: while (c = *s1++) ! 293: { ! 294: if ((c &= STRIP) == 0) ! 295: { ! 296: pushstak('/'); ! 297: break; ! 298: } ! 299: pushstak(c); ! 300: } ! 301: s1 = as2; ! 302: while (c = *s1++) ! 303: pushstak(c); ! 304: if (s1 = as3) ! 305: { ! 306: pushstak('/'); ! 307: do ! 308: pushstak(*++s1); ! 309: while(*s1); ! 310: } ! 311: makearg((struct argnod *)fixstak()); ! 312: } ! 313: ! 314: makearg(args) ! 315: register struct argnod *args; ! 316: { ! 317: args->argnxt = gchain; ! 318: gchain = args; ! 319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.