|
|
1.1 ! root 1: # ! 2: /* ! 3: * UNIX shell ! 4: * ! 5: * S. R. Bourne ! 6: * Bell Telephone Laboratories ! 7: * ! 8: */ ! 9: ! 10: #include "defs.h" ! 11: #include <sys/types.h> ! 12: #define DIRSIZ 15 ! 13: #include <sys/stat.h> ! 14: #include <sys/dir.h> ! 15: ! 16: ! 17: ! 18: /* globals (file name generation) ! 19: * ! 20: * "*" in params matches r.e ".*" ! 21: * "?" in params matches r.e. "." ! 22: * "[...]" in params matches character class ! 23: * "[...a-z...]" in params matches a through z. ! 24: * ! 25: */ ! 26: ! 27: PROC VOID addg(); ! 28: ! 29: ! 30: INT expand(as,rflg) ! 31: STRING as; ! 32: { ! 33: INT count, dirf; ! 34: BOOL dir=0; ! 35: STRING rescan = 0; ! 36: REG STRING s, cs; ! 37: ARGPTR schain = gchain; ! 38: struct direct entry; ! 39: STATBUF statb; ! 40: ! 41: IF trapnote&SIGSET THEN return(0); FI ! 42: ! 43: s=cs=as; entry.d_name[DIRSIZ-1]=0; /* to end the string */ ! 44: ! 45: /* check for meta chars */ ! 46: BEGIN ! 47: REG BOOL slash; slash=0; ! 48: WHILE !fngchar(*cs) ! 49: DO IF *cs++==0 ! 50: THEN IF rflg ANDF slash THEN break; ELSE return(0) FI ! 51: ELIF *cs=='/' ! 52: THEN slash++; ! 53: FI ! 54: OD ! 55: END ! 56: ! 57: LOOP IF cs==s ! 58: THEN s=nullstr; ! 59: break; ! 60: ELIF *--cs == '/' ! 61: THEN *cs=0; ! 62: IF s==cs THEN s="/" FI ! 63: break; ! 64: FI ! 65: POOL ! 66: IF stat(s,&statb)>=0 ! 67: ANDF (statb.st_mode&S_IFMT)==S_IFDIR ! 68: ANDF (dirf=open(s,0))>0 ! 69: THEN dir++; ! 70: FI ! 71: count=0; ! 72: IF *cs==0 THEN *cs++=0200 FI ! 73: IF dir ! 74: THEN /* check for rescan */ ! 75: REG STRING rs; rs=cs; ! 76: ! 77: REP IF *rs=='/' THEN rescan=rs; *rs=0; gchain=0 FI ! 78: PER *rs++ DONE ! 79: ! 80: WHILE read(dirf, &entry, 16) == 16 ANDF (trapnote&SIGSET) == 0 ! 81: DO IF entry.d_ino==0 ORF ! 82: (*entry.d_name=='.' ANDF *cs!='.') ! 83: THEN continue; ! 84: FI ! 85: IF gmatch(entry.d_name, cs) ! 86: THEN addg(s,entry.d_name,rescan); count++; ! 87: FI ! 88: OD ! 89: close(dirf); ! 90: ! 91: IF rescan ! 92: THEN REG ARGPTR rchain; ! 93: rchain=gchain; gchain=schain; ! 94: IF count ! 95: THEN count=0; ! 96: WHILE rchain ! 97: DO count += expand(rchain->argval,1); ! 98: rchain=rchain->argnxt; ! 99: OD ! 100: FI ! 101: *rescan='/'; ! 102: FI ! 103: FI ! 104: ! 105: BEGIN ! 106: REG CHAR c; ! 107: s=as; ! 108: WHILE c = *s ! 109: DO *s++=(c&STRIP?c:'/') OD ! 110: END ! 111: return(count); ! 112: } ! 113: ! 114: gmatch(s, p) ! 115: REG STRING s, p; ! 116: { ! 117: REG INT scc; ! 118: CHAR c; ! 119: ! 120: IF scc = *s++ ! 121: THEN IF (scc &= STRIP)==0 ! 122: THEN scc=0200; ! 123: FI ! 124: FI ! 125: SWITCH c = *p++ IN ! 126: ! 127: case '[': ! 128: {BOOL ok; INT lc; ! 129: ok=0; lc=077777; ! 130: WHILE c = *p++ ! 131: DO IF c==']' ! 132: THEN return(ok?gmatch(s,p):0); ! 133: ELIF c==MINUS ! 134: THEN IF lc<=scc ANDF scc<=(*p++) THEN ok++ FI ! 135: ELSE IF scc==(lc=(c&STRIP)) THEN ok++ FI ! 136: FI ! 137: OD ! 138: return(0); ! 139: } ! 140: ! 141: default: ! 142: IF (c&STRIP)!=scc THEN return(0) FI ! 143: ! 144: case '?': ! 145: return(scc?gmatch(s,p):0); ! 146: ! 147: case '*': ! 148: IF *p==0 THEN return(1) FI ! 149: --s; ! 150: WHILE *s ! 151: DO IF gmatch(s++,p) THEN return(1) FI OD ! 152: return(0); ! 153: ! 154: case 0: ! 155: return(scc==0); ! 156: ENDSW ! 157: } ! 158: ! 159: LOCAL VOID addg(as1,as2,as3) ! 160: STRING as1, as2, as3; ! 161: { ! 162: REG STRING s1, s2; ! 163: REG INT c; ! 164: ! 165: s2 = locstak()+BYTESPERWORD; ! 166: ! 167: s1=as1; ! 168: WHILE c = *s1++ ! 169: DO IF (c &= STRIP)==0 ! 170: THEN *s2++='/'; ! 171: break; ! 172: FI ! 173: *s2++=c; ! 174: OD ! 175: s1=as2; ! 176: WHILE *s2 = *s1++ DO s2++ OD ! 177: IF s1=as3 ! 178: THEN *s2++='/'; ! 179: WHILE *s2++ = *++s1 DONE ! 180: FI ! 181: makearg(endstak(s2)); ! 182: } ! 183: ! 184: makearg(args) ! 185: REG STRING args; ! 186: { ! 187: args->argnxt=gchain; ! 188: gchain=args; ! 189: } ! 190:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.