|
|
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: #ifndef BSD4_2 ! 13: #include <ndir.h> ! 14: #else ! 15: #include <sys/dir.h> ! 16: #endif ! 17: ! 18: #ifdef BSD4_2 ! 19: #define DIRSIZE MAXNAMELEN ! 20: #else ! 21: #define DIRSIZE 255 ! 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: BOOL dir = 0; ! 48: char *rescan = 0; ! 49: register char *s, *cs; ! 50: struct argnod *schain = gchain; ! 51: BOOL slash; ! 52: ! 53: if (trapnote & SIGSET) ! 54: return(0); ! 55: s = cs = as; ! 56: /* ! 57: * check for meta chars ! 58: */ ! 59: { ! 60: register BOOL open; ! 61: ! 62: slash = 0; ! 63: open = 0; ! 64: do ! 65: { ! 66: switch (*cs++) ! 67: { ! 68: case 0: ! 69: if (rcnt && slash) ! 70: break; ! 71: else ! 72: return(0); ! 73: ! 74: case '/': ! 75: slash++; ! 76: open = 0; ! 77: continue; ! 78: ! 79: case '[': ! 80: open++; ! 81: continue; ! 82: ! 83: case ']': ! 84: if (open == 0) ! 85: continue; ! 86: ! 87: case '?': ! 88: case '*': ! 89: if (rcnt > slash) ! 90: continue; ! 91: else ! 92: cs--; ! 93: break; ! 94: ! 95: ! 96: default: ! 97: continue; ! 98: } ! 99: break; ! 100: } while (TRUE); ! 101: } ! 102: ! 103: for (;;) ! 104: { ! 105: if (cs == s) ! 106: { ! 107: s = nullstr; ! 108: break; ! 109: } ! 110: else if (*--cs == '/') ! 111: { ! 112: *cs = 0; ! 113: if (s == cs) ! 114: s = "/"; ! 115: break; ! 116: } ! 117: } ! 118: ! 119: if ((dirf = opendir(*s ? s : ".")) != 0) ! 120: dir = TRUE; ! 121: ! 122: count = 0; ! 123: if (*cs == 0) ! 124: *cs++ = 0200; ! 125: ! 126: if(dir) ! 127: { ! 128: register char *rs; ! 129: struct direct *e; ! 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: ! 146: if (entry[0] == '.' && *cs != '.') ! 147: { ! 148: if (entry[1] == 0) ! 149: continue; ! 150: if (entry[1] == '.' && entry[2] == 0) ! 151: continue; ! 152: } ! 153: ! 154: if (gmatch(entry, cs)) ! 155: { ! 156: addg(s, entry, rescan); ! 157: count++; ! 158: } ! 159: } ! 160: closedir(dirf); ! 161: ! 162: if (rescan) ! 163: { ! 164: register struct argnod *rchain; ! 165: ! 166: rchain = gchain; ! 167: gchain = schain; ! 168: if (count) ! 169: { ! 170: count = 0; ! 171: while (rchain) ! 172: { ! 173: count += expand(rchain->argval, slash + 1); ! 174: rchain = rchain->argnxt; ! 175: } ! 176: } ! 177: *rescan = '/'; ! 178: } ! 179: } ! 180: ! 181: { ! 182: register char c; ! 183: ! 184: s = as; ! 185: while (c = *s) ! 186: *s++ = (c & STRIP ? c : '/'); ! 187: } ! 188: return(count); ! 189: } ! 190: ! 191: ! 192: ! 193: gmatch(s, p) ! 194: register char *s, *p; ! 195: { ! 196: register int scc; ! 197: char c; ! 198: ! 199: if (scc = *s++) ! 200: { ! 201: if ((scc &= STRIP) == 0) ! 202: scc=0200; ! 203: } ! 204: switch (c = *p++) ! 205: { ! 206: case '[': ! 207: { ! 208: BOOL ok; ! 209: int lc; ! 210: int notflag = 0; ! 211: ! 212: ok = 0; ! 213: lc = 077777; ! 214: if (*p == '^') ! 215: { ! 216: notflag = 1; ! 217: p++; ! 218: } ! 219: while (c = *p++) ! 220: { ! 221: if (c == ']') ! 222: return(ok ? gmatch(s, p) : 0); ! 223: else if (c == MINUS) ! 224: { ! 225: if (notflag) ! 226: { ! 227: if (scc < lc || scc > *(p++)) ! 228: ok++; ! 229: else ! 230: return(0); ! 231: } ! 232: else ! 233: { ! 234: if (lc <= scc && scc <= (*p++)) ! 235: ok++; ! 236: } ! 237: } ! 238: else ! 239: { ! 240: lc = c & STRIP; ! 241: if (notflag) ! 242: { ! 243: if (scc && scc != lc) ! 244: ok++; ! 245: else ! 246: return(0); ! 247: } ! 248: else ! 249: { ! 250: if (scc == lc) ! 251: ok++; ! 252: } ! 253: } ! 254: } ! 255: return(0); ! 256: } ! 257: ! 258: default: ! 259: if ((c & STRIP) != scc) ! 260: return(0); ! 261: ! 262: case '?': ! 263: return(scc ? gmatch(s, p) : 0); ! 264: ! 265: case '*': ! 266: while (*p == '*') ! 267: p++; ! 268: ! 269: if (*p == 0) ! 270: return(1); ! 271: --s; ! 272: while (*s) ! 273: { ! 274: if (gmatch(s++, p)) ! 275: return(1); ! 276: } ! 277: return(0); ! 278: ! 279: case 0: ! 280: return(scc == 0); ! 281: } ! 282: } ! 283: ! 284: static ! 285: addg(as1, as2, as3) ! 286: char *as1, *as2, *as3; ! 287: { ! 288: register char *s1; ! 289: register int c; ! 290: ! 291: staktop = locstak() + BYTESPERWORD; ! 292: s1 = as1; ! 293: while (c = *s1++) ! 294: { ! 295: if ((c &= STRIP) == 0) ! 296: { ! 297: pushstak('/'); ! 298: break; ! 299: } ! 300: pushstak(c); ! 301: } ! 302: s1 = as2; ! 303: while (c = *s1++) ! 304: pushstak(c); ! 305: if (s1 = as3) ! 306: { ! 307: pushstak('/'); ! 308: do ! 309: pushstak(*++s1); ! 310: while(*s1); ! 311: } ! 312: makearg(fixstak()); ! 313: } ! 314: ! 315: makearg(args) ! 316: register struct argnod *args; ! 317: { ! 318: args->argnxt = gchain; ! 319: gchain = args; ! 320: } ! 321: ! 322: ! 323: DIR * ! 324: opendir(name) ! 325: register char *name; ! 326: { ! 327: DIR dirbuf, *dirp; ! 328: struct stat statb; ! 329: char buf[MAXNAMELEN+1]; ! 330: register char *s; ! 331: ! 332: *(movstrn(name, buf, MAXNAMELEN)) = 0; ! 333: for (s=buf; *s; s++) ! 334: *s &= STRIP; ! 335: if ((dirbuf.dd_fd = open(buf, 0)) < 0) ! 336: return(NULL); ! 337: if (fstat(dirbuf.dd_fd, &statb)!=0 || (statb.st_mode & S_IFMT)!=S_IFDIR){ ! 338: close(dirbuf.dd_fd); ! 339: return(NULL); ! 340: } ! 341: dirbuf.dd_size = dirbuf.dd_loc = 0; ! 342: dirp = (DIR *)shalloc(sizeof(DIR)); ! 343: *dirp = dirbuf; ! 344: return(dirp); ! 345: } ! 346: ! 347: void ! 348: closedir(dirp) ! 349: DIR *dirp; ! 350: { ! 351: close(dirp->dd_fd); ! 352: shfree((char *)dirp); ! 353: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.