114479Ssam #ifndef lint 2*37678Sbostic static char sccsid[] = "@(#)service.c 4.7 05/08/89"; 314479Ssam #endif 46702Smckusick 56702Smckusick # 66702Smckusick /* 76702Smckusick * UNIX shell 86702Smckusick * 96702Smckusick * S. R. Bourne 106702Smckusick * Bell Telephone Laboratories 116702Smckusick * 126702Smckusick */ 136702Smckusick 146702Smckusick #include "defs.h" 1535773Sbostic #include "errno.h" 16*37678Sbostic #include "pathnames.h" 176702Smckusick 186702Smckusick 196702Smckusick PROC VOID gsort(); 206702Smckusick 216702Smckusick #define ARGMK 01 226702Smckusick 236702Smckusick INT errno; 246702Smckusick STRING sysmsg[]; 2518430Smckusick INT num_sysmsg; 266702Smckusick 276702Smckusick /* service routines for `execute' */ 286702Smckusick 296702Smckusick VOID initio(iop) 306702Smckusick IOPTR iop; 316702Smckusick { 326702Smckusick REG STRING ion; 336702Smckusick REG INT iof, fd; 346702Smckusick 356702Smckusick IF iop 366702Smckusick THEN iof=iop->iofile; 376702Smckusick ion=mactrim(iop->ioname); 386702Smckusick IF *ion ANDF (flags&noexec)==0 396702Smckusick THEN IF iof&IODOC 406702Smckusick THEN subst(chkopen(ion),(fd=tmpfil())); 416702Smckusick close(fd); fd=chkopen(tmpout); unlink(tmpout); 426702Smckusick ELIF iof&IOMOV 436702Smckusick THEN IF eq(minus,ion) 446702Smckusick THEN fd = -1; 456702Smckusick close(iof&IOUFD); 466702Smckusick ELIF (fd=stoi(ion))>=USERIO 476702Smckusick THEN failed(ion,badfile); 486702Smckusick ELSE fd=dup(fd); 496702Smckusick FI 506702Smckusick ELIF (iof&IOPUT)==0 516702Smckusick THEN fd=chkopen(ion); 526702Smckusick ELIF flags&rshflg 536702Smckusick THEN failed(ion,restricted); 546702Smckusick ELIF iof&IOAPP ANDF (fd=open(ion,1))>=0 556702Smckusick THEN lseek(fd, 0L, 2); 566702Smckusick ELSE fd=create(ion); 576702Smckusick FI 586702Smckusick IF fd>=0 596702Smckusick THEN rename(fd,iof&IOUFD); 606702Smckusick FI 616702Smckusick FI 626702Smckusick initio(iop->ionxt); 636702Smckusick FI 646702Smckusick } 656702Smckusick 666702Smckusick STRING getpath(s) 676702Smckusick STRING s; 686702Smckusick { 696702Smckusick REG STRING path; 706702Smckusick IF any('/',s) 716702Smckusick THEN IF flags&rshflg 726702Smckusick THEN failed(s, restricted); 736702Smckusick ELSE return(nullstr); 746702Smckusick FI 756702Smckusick ELIF (path = pathnod.namval)==0 76*37678Sbostic THEN return(_PATH_DEFPATH); 776702Smckusick ELSE return(cpystak(path)); 786702Smckusick FI 796702Smckusick } 806702Smckusick 816702Smckusick INT pathopen(path, name) 826702Smckusick REG STRING path, name; 836702Smckusick { 846702Smckusick REG UFD f; 856702Smckusick 866702Smckusick REP path=catpath(path,name); 876702Smckusick PER (f=open(curstak(),0))<0 ANDF path DONE 886702Smckusick return(f); 896702Smckusick } 906702Smckusick 916702Smckusick STRING catpath(path,name) 926702Smckusick REG STRING path; 936702Smckusick STRING name; 946702Smckusick { 956702Smckusick /* leaves result on top of stack */ 966702Smckusick REG STRING scanp = path, 976702Smckusick argp = locstak(); 986702Smckusick 996702Smckusick WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD 1006702Smckusick IF scanp!=path THEN *argp++='/' FI 1016702Smckusick IF *scanp==COLON THEN scanp++ FI 1026702Smckusick path=(*scanp ? scanp : 0); scanp=name; 1036702Smckusick WHILE (*argp++ = *scanp++) DONE 1046702Smckusick return(path); 1056702Smckusick } 1066702Smckusick 1076702Smckusick LOCAL STRING xecmsg; 1086702Smckusick LOCAL STRING *xecenv; 1096702Smckusick 1106702Smckusick VOID execa(at) 1116702Smckusick STRING at[]; 1126702Smckusick { 1136702Smckusick REG STRING path; 1146702Smckusick REG STRING *t = at; 1156702Smckusick 1166702Smckusick IF (flags&noexec)==0 1176702Smckusick THEN xecmsg=notfound; path=getpath(*t); 1186702Smckusick namscan(exname); 1196702Smckusick xecenv=setenv(); 1206702Smckusick WHILE path=execs(path,t) DONE 1216702Smckusick failed(*t,xecmsg); 1226702Smckusick FI 1236702Smckusick } 1246702Smckusick 1256702Smckusick LOCAL STRING execs(ap,t) 1266702Smckusick STRING ap; 1276702Smckusick REG STRING t[]; 1286702Smckusick { 1296702Smckusick REG STRING p, prefix; 1306702Smckusick 1316702Smckusick prefix=catpath(ap,t[0]); 1326702Smckusick trim(p=curstak()); 1336702Smckusick 1346702Smckusick sigchk(); 1356702Smckusick execve(p, &t[0] ,xecenv); 1366702Smckusick SWITCH errno IN 1376702Smckusick 1386702Smckusick case ENOEXEC: 1396702Smckusick flags=0; 1406702Smckusick comdiv=0; ioset=0; 1416702Smckusick clearup(); /* remove open files and for loop junk */ 1426702Smckusick IF input THEN close(input) FI 1436702Smckusick close(output); output=2; 1446702Smckusick input=chkopen(p); 1456702Smckusick 1466702Smckusick /* band aid to get csh... 2/26/79 */ 1476702Smckusick { 1486702Smckusick char c; 1496702Smckusick if (!isatty(input)) { 1506702Smckusick read(input, &c, 1); 1516702Smckusick if (c == '#') 1526702Smckusick gocsh(t, p, xecenv); 1536702Smckusick lseek(input, (long) 0, 0); 1546702Smckusick } 1556702Smckusick } 1566702Smckusick 1576702Smckusick /* set up new args */ 1586702Smckusick setargs(t); 1596702Smckusick longjmp(subshell,1); 1606702Smckusick 1616702Smckusick case ENOMEM: 1626702Smckusick failed(p,toobig); 1636702Smckusick 1646702Smckusick case E2BIG: 1656702Smckusick failed(p,arglist); 1666702Smckusick 1676702Smckusick case ETXTBSY: 1686702Smckusick failed(p,txtbsy); 1696702Smckusick 1706702Smckusick default: 1716702Smckusick xecmsg=badexec; 1726702Smckusick case ENOENT: 1736702Smckusick return(prefix); 1746702Smckusick ENDSW 1756702Smckusick } 1766702Smckusick 1776702Smckusick gocsh(t, cp, xecenv) 1786702Smckusick register char **t, *cp, **xecenv; 1796702Smckusick { 1806702Smckusick char **newt[1000]; 1816702Smckusick register char **p; 1826702Smckusick register int i; 1836702Smckusick 1846702Smckusick for (i = 0; t[i]; i++) 1856702Smckusick newt[i+1] = t[i]; 1866702Smckusick newt[i+1] = 0; 187*37678Sbostic newt[0] = _PATH_CSHELL; 1886702Smckusick newt[1] = cp; 189*37678Sbostic execve(_PATH_CSHELL, newt, xecenv); 1906702Smckusick } 1916702Smckusick 1926702Smckusick /* for processes to be waited for */ 1936702Smckusick #define MAXP 20 1946702Smckusick LOCAL INT pwlist[MAXP]; 1956702Smckusick LOCAL INT pwc; 1966702Smckusick 1976702Smckusick postclr() 1986702Smckusick { 1996702Smckusick REG INT *pw = pwlist; 2006702Smckusick 2016702Smckusick WHILE pw <= &pwlist[pwc] 2026702Smckusick DO *pw++ = 0 OD 2036702Smckusick pwc=0; 2046702Smckusick } 2056702Smckusick 2066702Smckusick VOID post(pcsid) 2076702Smckusick INT pcsid; 2086702Smckusick { 2096702Smckusick REG INT *pw = pwlist; 2106702Smckusick 2116702Smckusick IF pcsid 2126702Smckusick THEN WHILE *pw DO pw++ OD 2136702Smckusick IF pwc >= MAXP-1 2146702Smckusick THEN pw--; 2156702Smckusick ELSE pwc++; 2166702Smckusick FI 2176702Smckusick *pw = pcsid; 2186702Smckusick FI 2196702Smckusick } 2206702Smckusick 2216702Smckusick VOID await(i) 2226702Smckusick INT i; 2236702Smckusick { 2246702Smckusick INT rc=0, wx=0; 2256702Smckusick INT w; 2266702Smckusick INT ipwc = pwc; 2276702Smckusick 2286702Smckusick post(i); 2296702Smckusick WHILE pwc 2306702Smckusick DO REG INT p; 2316702Smckusick REG INT sig; 2326702Smckusick INT w_hi; 2336702Smckusick 2346702Smckusick BEGIN 2356702Smckusick REG INT *pw=pwlist; 23614935Smckusick IF setjmp(INTbuf) == 0 23714935Smckusick THEN trapjmp[INTR] = 1; p=wait(&w); 23814935Smckusick ELSE p = -1; 23914935Smckusick FI 24014935Smckusick trapjmp[INTR] = 0; 2416702Smckusick WHILE pw <= &pwlist[ipwc] 2426702Smckusick DO IF *pw==p 2436702Smckusick THEN *pw=0; pwc--; 2446702Smckusick ELSE pw++; 2456702Smckusick FI 2466702Smckusick OD 2476702Smckusick END 2486702Smckusick 2496702Smckusick IF p == -1 THEN continue FI 2506702Smckusick 2516702Smckusick w_hi = (w>>8)&LOBYTE; 2526702Smckusick 2536702Smckusick IF sig = w&0177 2546702Smckusick THEN IF sig == 0177 /* ptrace! return */ 2556702Smckusick THEN prs("ptrace: "); 2566702Smckusick sig = w_hi; 2576702Smckusick FI 25818430Smckusick IF sig < num_sysmsg ANDF sysmsg[sig] 25918430Smckusick THEN IF i!=p ORF (flags&prompt)==0 26018430Smckusick THEN prp(); prn(p); blank() 26118430Smckusick FI 2626702Smckusick prs(sysmsg[sig]); 2636702Smckusick IF w&0200 THEN prs(coredump) FI 2646702Smckusick FI 2656702Smckusick newline(); 2666702Smckusick FI 2676702Smckusick 2686702Smckusick IF rc==0 2696702Smckusick THEN rc = (sig ? sig|SIGFLG : w_hi); 2706702Smckusick FI 2716702Smckusick wx |= w; 2726702Smckusick OD 2736702Smckusick 2746702Smckusick IF wx ANDF flags&errflg 2756702Smckusick THEN exitsh(rc); 2766702Smckusick FI 2776702Smckusick exitval=rc; exitset(); 2786702Smckusick } 2796702Smckusick 2806702Smckusick BOOL nosubst; 2816702Smckusick 2826702Smckusick trim(at) 2836702Smckusick STRING at; 2846702Smckusick { 2856702Smckusick REG STRING p; 2866702Smckusick REG CHAR c; 2876702Smckusick REG CHAR q=0; 2886702Smckusick 2896702Smckusick IF p=at 2906702Smckusick THEN WHILE c = *p 2916702Smckusick DO *p++=c&STRIP; q |= c OD 2926702Smckusick FI 2936702Smckusick nosubst=q"E; 2946702Smckusick } 2956702Smckusick 2966702Smckusick STRING mactrim(s) 2976702Smckusick STRING s; 2986702Smckusick { 2996702Smckusick REG STRING t=macro(s); 3006702Smckusick trim(t); 3016702Smckusick return(t); 3026702Smckusick } 3036702Smckusick 3046702Smckusick STRING *scan(argn) 3056702Smckusick INT argn; 3066702Smckusick { 3076702Smckusick REG ARGPTR argp = Rcheat(gchain)&~ARGMK; 3086702Smckusick REG STRING *comargn, *comargm; 3096702Smckusick 3106702Smckusick comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS; 3116702Smckusick 3126702Smckusick WHILE argp 3136702Smckusick DO *--comargn = argp->argval; 3146702Smckusick IF argp = argp->argnxt 3156702Smckusick THEN trim(*comargn); 3166702Smckusick FI 3176702Smckusick IF argp==0 ORF Rcheat(argp)&ARGMK 3186702Smckusick THEN gsort(comargn,comargm); 3196702Smckusick comargm = comargn; 3206702Smckusick FI 3216702Smckusick /* Lcheat(argp) &= ~ARGMK; */ 3226702Smckusick argp = Rcheat(argp)&~ARGMK; 3236702Smckusick OD 3246702Smckusick return(comargn); 3256702Smckusick } 3266702Smckusick 3276702Smckusick LOCAL VOID gsort(from,to) 3286702Smckusick STRING from[], to[]; 3296702Smckusick { 3306702Smckusick INT k, m, n; 3316702Smckusick REG INT i, j; 3326702Smckusick 3336702Smckusick IF (n=to-from)<=1 THEN return FI 3346702Smckusick 3356702Smckusick FOR j=1; j<=n; j*=2 DONE 3366702Smckusick 3376702Smckusick FOR m=2*j-1; m/=2; 3386702Smckusick DO k=n-m; 3396702Smckusick FOR j=0; j<k; j++ 3406702Smckusick DO FOR i=j; i>=0; i-=m 3416702Smckusick DO REG STRING *fromi; fromi = &from[i]; 3426702Smckusick IF cf(fromi[m],fromi[0])>0 3436702Smckusick THEN break; 3446702Smckusick ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s; 3456702Smckusick FI 3466702Smckusick OD 3476702Smckusick OD 3486702Smckusick OD 3496702Smckusick } 3506702Smckusick 3516702Smckusick /* Argument list generation */ 3526702Smckusick 3536702Smckusick INT getarg(ac) 3546702Smckusick COMPTR ac; 3556702Smckusick { 3566702Smckusick REG ARGPTR argp; 3576702Smckusick REG INT count=0; 3586702Smckusick REG COMPTR c; 3596702Smckusick 3606702Smckusick IF c=ac 3616702Smckusick THEN argp=c->comarg; 3626702Smckusick WHILE argp 3636702Smckusick DO count += split(macro(argp->argval)); 3646702Smckusick argp=argp->argnxt; 3656702Smckusick OD 3666702Smckusick FI 3676702Smckusick return(count); 3686702Smckusick } 3696702Smckusick 3706702Smckusick LOCAL INT split(s) 3716702Smckusick REG STRING s; 3726702Smckusick { 3736702Smckusick REG STRING argp; 3746702Smckusick REG INT c; 3756702Smckusick INT count=0; 3766702Smckusick 3776702Smckusick LOOP sigchk(); argp=locstak()+BYTESPERWORD; 3786702Smckusick WHILE (c = *s++, !any(c,ifsnod.namval) && c) 3796702Smckusick DO *argp++ = c OD 3806702Smckusick IF argp==staktop+BYTESPERWORD 3816702Smckusick THEN IF c 3826702Smckusick THEN continue; 3836702Smckusick ELSE return(count); 3846702Smckusick FI 3856702Smckusick ELIF c==0 3866702Smckusick THEN s--; 3876702Smckusick FI 38834082Sbostic IF c=expand(((ARGPTR)(argp=endstak(argp)))->argval,0) 3896702Smckusick THEN count += c; 3906702Smckusick ELSE /* assign(&fngnod, argp->argval); */ 3916702Smckusick makearg(argp); count++; 3926702Smckusick FI 3936702Smckusick Lcheat(gchain) |= ARGMK; 3946702Smckusick POOL 3956702Smckusick } 396