|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)service.c 4.3 9/9/83"; ! 3: #endif ! 4: ! 5: # ! 6: /* ! 7: * UNIX shell ! 8: * ! 9: * S. R. Bourne ! 10: * Bell Telephone Laboratories ! 11: * ! 12: */ ! 13: ! 14: #include "defs.h" ! 15: ! 16: ! 17: PROC VOID gsort(); ! 18: ! 19: #define ARGMK 01 ! 20: ! 21: INT errno; ! 22: STRING sysmsg[]; ! 23: ! 24: /* fault handling */ ! 25: #define ENOMEM 12 ! 26: #define ENOEXEC 8 ! 27: #define E2BIG 7 ! 28: #define ENOENT 2 ! 29: #define ETXTBSY 26 ! 30: ! 31: ! 32: ! 33: /* service routines for `execute' */ ! 34: ! 35: VOID initio(iop) ! 36: IOPTR iop; ! 37: { ! 38: REG STRING ion; ! 39: REG INT iof, fd; ! 40: ! 41: IF iop ! 42: THEN iof=iop->iofile; ! 43: ion=mactrim(iop->ioname); ! 44: IF *ion ANDF (flags&noexec)==0 ! 45: THEN IF iof&IODOC ! 46: THEN subst(chkopen(ion),(fd=tmpfil())); ! 47: close(fd); fd=chkopen(tmpout); unlink(tmpout); ! 48: ELIF iof&IOMOV ! 49: THEN IF eq(minus,ion) ! 50: THEN fd = -1; ! 51: close(iof&IOUFD); ! 52: ELIF (fd=stoi(ion))>=USERIO ! 53: THEN failed(ion,badfile); ! 54: ELSE fd=dup(fd); ! 55: FI ! 56: ELIF (iof&IOPUT)==0 ! 57: THEN fd=chkopen(ion); ! 58: ELIF flags&rshflg ! 59: THEN failed(ion,restricted); ! 60: ELIF iof&IOAPP ANDF (fd=open(ion,1))>=0 ! 61: THEN lseek(fd, 0L, 2); ! 62: ELSE fd=create(ion); ! 63: FI ! 64: IF fd>=0 ! 65: THEN rename(fd,iof&IOUFD); ! 66: FI ! 67: FI ! 68: initio(iop->ionxt); ! 69: FI ! 70: } ! 71: ! 72: STRING getpath(s) ! 73: STRING s; ! 74: { ! 75: REG STRING path; ! 76: IF any('/',s) ! 77: THEN IF flags&rshflg ! 78: THEN failed(s, restricted); ! 79: ELSE return(nullstr); ! 80: FI ! 81: ELIF (path = pathnod.namval)==0 ! 82: THEN return(defpath); ! 83: ELSE return(cpystak(path)); ! 84: FI ! 85: } ! 86: ! 87: INT pathopen(path, name) ! 88: REG STRING path, name; ! 89: { ! 90: REG UFD f; ! 91: ! 92: REP path=catpath(path,name); ! 93: PER (f=open(curstak(),0))<0 ANDF path DONE ! 94: return(f); ! 95: } ! 96: ! 97: STRING catpath(path,name) ! 98: REG STRING path; ! 99: STRING name; ! 100: { ! 101: /* leaves result on top of stack */ ! 102: REG STRING scanp = path, ! 103: argp = locstak(); ! 104: ! 105: WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD ! 106: IF scanp!=path THEN *argp++='/' FI ! 107: IF *scanp==COLON THEN scanp++ FI ! 108: path=(*scanp ? scanp : 0); scanp=name; ! 109: WHILE (*argp++ = *scanp++) DONE ! 110: return(path); ! 111: } ! 112: ! 113: LOCAL STRING xecmsg; ! 114: LOCAL STRING *xecenv; ! 115: ! 116: VOID execa(at) ! 117: STRING at[]; ! 118: { ! 119: REG STRING path; ! 120: REG STRING *t = at; ! 121: ! 122: IF (flags&noexec)==0 ! 123: THEN xecmsg=notfound; path=getpath(*t); ! 124: namscan(exname); ! 125: xecenv=setenv(); ! 126: WHILE path=execs(path,t) DONE ! 127: failed(*t,xecmsg); ! 128: FI ! 129: } ! 130: ! 131: LOCAL STRING execs(ap,t) ! 132: STRING ap; ! 133: REG STRING t[]; ! 134: { ! 135: REG STRING p, prefix; ! 136: ! 137: prefix=catpath(ap,t[0]); ! 138: trim(p=curstak()); ! 139: ! 140: sigchk(); ! 141: execve(p, &t[0] ,xecenv); ! 142: SWITCH errno IN ! 143: ! 144: case ENOEXEC: ! 145: flags=0; ! 146: comdiv=0; ioset=0; ! 147: clearup(); /* remove open files and for loop junk */ ! 148: IF input THEN close(input) FI ! 149: close(output); output=2; ! 150: input=chkopen(p); ! 151: ! 152: /* band aid to get csh... 2/26/79 */ ! 153: { ! 154: char c; ! 155: if (!isatty(input)) { ! 156: read(input, &c, 1); ! 157: if (c == '#') ! 158: gocsh(t, p, xecenv); ! 159: lseek(input, (long) 0, 0); ! 160: } ! 161: } ! 162: ! 163: /* set up new args */ ! 164: setargs(t); ! 165: longjmp(subshell,1); ! 166: ! 167: case ENOMEM: ! 168: failed(p,toobig); ! 169: ! 170: case E2BIG: ! 171: failed(p,arglist); ! 172: ! 173: case ETXTBSY: ! 174: failed(p,txtbsy); ! 175: ! 176: default: ! 177: xecmsg=badexec; ! 178: case ENOENT: ! 179: return(prefix); ! 180: ENDSW ! 181: } ! 182: ! 183: gocsh(t, cp, xecenv) ! 184: register char **t, *cp, **xecenv; ! 185: { ! 186: char **newt[1000]; ! 187: register char **p; ! 188: register int i; ! 189: ! 190: for (i = 0; t[i]; i++) ! 191: newt[i+1] = t[i]; ! 192: newt[i+1] = 0; ! 193: newt[0] = "/bin/csh"; ! 194: newt[1] = cp; ! 195: execve("/bin/csh", newt, xecenv); ! 196: } ! 197: ! 198: /* for processes to be waited for */ ! 199: #define MAXP 20 ! 200: LOCAL INT pwlist[MAXP]; ! 201: LOCAL INT pwc; ! 202: ! 203: postclr() ! 204: { ! 205: REG INT *pw = pwlist; ! 206: ! 207: WHILE pw <= &pwlist[pwc] ! 208: DO *pw++ = 0 OD ! 209: pwc=0; ! 210: } ! 211: ! 212: VOID post(pcsid) ! 213: INT pcsid; ! 214: { ! 215: REG INT *pw = pwlist; ! 216: ! 217: IF pcsid ! 218: THEN WHILE *pw DO pw++ OD ! 219: IF pwc >= MAXP-1 ! 220: THEN pw--; ! 221: ELSE pwc++; ! 222: FI ! 223: *pw = pcsid; ! 224: FI ! 225: } ! 226: ! 227: VOID await(i) ! 228: INT i; ! 229: { ! 230: INT rc=0, wx=0; ! 231: INT w; ! 232: INT ipwc = pwc; ! 233: ! 234: post(i); ! 235: WHILE pwc ! 236: DO REG INT p; ! 237: REG INT sig; ! 238: INT w_hi; ! 239: ! 240: BEGIN ! 241: REG INT *pw=pwlist; ! 242: IF setjmp(INTbuf) == 0 ! 243: THEN trapjmp[INTR] = 1; p=wait(&w); ! 244: ELSE p = -1; ! 245: FI ! 246: trapjmp[INTR] = 0; ! 247: WHILE pw <= &pwlist[ipwc] ! 248: DO IF *pw==p ! 249: THEN *pw=0; pwc--; ! 250: ELSE pw++; ! 251: FI ! 252: OD ! 253: END ! 254: ! 255: IF p == -1 THEN continue FI ! 256: ! 257: w_hi = (w>>8)&LOBYTE; ! 258: ! 259: IF sig = w&0177 ! 260: THEN IF sig == 0177 /* ptrace! return */ ! 261: THEN prs("ptrace: "); ! 262: sig = w_hi; ! 263: FI ! 264: IF sysmsg[sig] ! 265: THEN IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI ! 266: prs(sysmsg[sig]); ! 267: IF w&0200 THEN prs(coredump) FI ! 268: FI ! 269: newline(); ! 270: FI ! 271: ! 272: IF rc==0 ! 273: THEN rc = (sig ? sig|SIGFLG : w_hi); ! 274: FI ! 275: wx |= w; ! 276: OD ! 277: ! 278: IF wx ANDF flags&errflg ! 279: THEN exitsh(rc); ! 280: FI ! 281: exitval=rc; exitset(); ! 282: } ! 283: ! 284: BOOL nosubst; ! 285: ! 286: trim(at) ! 287: STRING at; ! 288: { ! 289: REG STRING p; ! 290: REG CHAR c; ! 291: REG CHAR q=0; ! 292: ! 293: IF p=at ! 294: THEN WHILE c = *p ! 295: DO *p++=c&STRIP; q |= c OD ! 296: FI ! 297: nosubst=q"E; ! 298: } ! 299: ! 300: STRING mactrim(s) ! 301: STRING s; ! 302: { ! 303: REG STRING t=macro(s); ! 304: trim(t); ! 305: return(t); ! 306: } ! 307: ! 308: STRING *scan(argn) ! 309: INT argn; ! 310: { ! 311: REG ARGPTR argp = Rcheat(gchain)&~ARGMK; ! 312: REG STRING *comargn, *comargm; ! 313: ! 314: comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS; ! 315: ! 316: WHILE argp ! 317: DO *--comargn = argp->argval; ! 318: IF argp = argp->argnxt ! 319: THEN trim(*comargn); ! 320: FI ! 321: IF argp==0 ORF Rcheat(argp)&ARGMK ! 322: THEN gsort(comargn,comargm); ! 323: comargm = comargn; ! 324: FI ! 325: /* Lcheat(argp) &= ~ARGMK; */ ! 326: argp = Rcheat(argp)&~ARGMK; ! 327: OD ! 328: return(comargn); ! 329: } ! 330: ! 331: LOCAL VOID gsort(from,to) ! 332: STRING from[], to[]; ! 333: { ! 334: INT k, m, n; ! 335: REG INT i, j; ! 336: ! 337: IF (n=to-from)<=1 THEN return FI ! 338: ! 339: FOR j=1; j<=n; j*=2 DONE ! 340: ! 341: FOR m=2*j-1; m/=2; ! 342: DO k=n-m; ! 343: FOR j=0; j<k; j++ ! 344: DO FOR i=j; i>=0; i-=m ! 345: DO REG STRING *fromi; fromi = &from[i]; ! 346: IF cf(fromi[m],fromi[0])>0 ! 347: THEN break; ! 348: ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s; ! 349: FI ! 350: OD ! 351: OD ! 352: OD ! 353: } ! 354: ! 355: /* Argument list generation */ ! 356: ! 357: INT getarg(ac) ! 358: COMPTR ac; ! 359: { ! 360: REG ARGPTR argp; ! 361: REG INT count=0; ! 362: REG COMPTR c; ! 363: ! 364: IF c=ac ! 365: THEN argp=c->comarg; ! 366: WHILE argp ! 367: DO count += split(macro(argp->argval)); ! 368: argp=argp->argnxt; ! 369: OD ! 370: FI ! 371: return(count); ! 372: } ! 373: ! 374: LOCAL INT split(s) ! 375: REG STRING s; ! 376: { ! 377: REG STRING argp; ! 378: REG INT c; ! 379: INT count=0; ! 380: ! 381: LOOP sigchk(); argp=locstak()+BYTESPERWORD; ! 382: WHILE (c = *s++, !any(c,ifsnod.namval) && c) ! 383: DO *argp++ = c OD ! 384: IF argp==staktop+BYTESPERWORD ! 385: THEN IF c ! 386: THEN continue; ! 387: ELSE return(count); ! 388: FI ! 389: ELIF c==0 ! 390: THEN s--; ! 391: FI ! 392: IF c=expand((argp=endstak(argp))->argval,0) ! 393: THEN count += c; ! 394: ELSE /* assign(&fngnod, argp->argval); */ ! 395: makearg(argp); count++; ! 396: FI ! 397: Lcheat(gchain) |= ARGMK; ! 398: POOL ! 399: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.