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