# /* send3.c */ /* This information is proprietary and is the property of Bell Telephone Laboratories, Incorporated. Its reproduction or disclosure to others, either orally or in writing, is pro- hibited without written permission of Bell Laboratories. */ #define IDMOD send3 #define IDSTR "~|^`send3.c 1.10 4/22/76 #include "send.h" doarg(ctx,n,s,eof) struct context *ctx; char *s; int *eof; {static int nsh; char *px,*avv,vv[LNX]; int ndo,k,nv,vt,vx,pd[2]; struct keywd *pk; register int i; register char *p; register struct context *x; avv=vv; x=ctx; if (abort) {if (x->sfd>0) unlink(x->stm); x->sfd=0; return (1);}; px=(p=s)+n; for (i=0;p<px;) {if ((k=0177&(*p++))=='\\') {if (p<px) k=0200|(*p++);}; ss[i]=k; if (i<LNL) i++;}; if (i>=LNL) i=LNL-1; px=(p=avv)+(nv=i); for (i=0;p<px;) *p++=0177&ss[i++]; *p=0; vt=type(nv,ss,&vx); if (vt==TDOL) {if (x->sfd==0) {prf("%q/tmp/sh",x->stm); x->sfd=i=mktmp(x->stm,nsh++); if (i>0) inibf(&tbf,i);}; if (x->sfd>0) putl(&tbf,nv-1,avv+1); return (0);}; ndo=0; if (x->sfd) {if (x->sfd<0) {p="(create)"; goto NS;}; flush(&tbf); close(x->sfd); if (xpipe(pd)<0) {p="(pipe)"; goto NS;}; if ((i=tfork())==(-1)) {p="(fork)"; NS: k=diag(x,"cannot run shell",p,587); goto XS;}; if (i==0) {close(0); open("/dev/null",0); close(1); dup(pd[1]); execl("/bin/sh","sh",x->stm,0); exit(040);}; close(pd[1]); ndo=|dofile(pd[0],x->stm,x,TDOL); k=shex(x); XS: if (k && (i=open(x->stm,0))>=0) {inibf(&tbf,i); while ((i=getl(&tbf,ss))>=0) putl(&dbf,i,ss); close(tbf.fd);}; if (x->sfd>0) unlink(x->stm); x->sfd=0;}; switch (vt) {case TCOM: break; case TEOF: *eof=1; break; case TINP: ndo=|dofile(0,"-",x,vt); break; case TTTY: ndo=|dofile(dup(getty()),"+",x,vt); break; case TMSG: *px='\n'; write(getty(),avv+1,nv); break; case TPIN: *px='\n'; if (tin) {write(getty(),avv+2,nv-1); vt=TPTY;}; *px=0; ndo=|dofile(0,avv,x,vt); break; case TPTY: *px='\n'; write(getty(),avv+2,nv-1); *px=0; ndo=|dofile(dup(getty()),avv,x,vt); break; case TFMT: i=0; ss[i++]='<'; for (p=avv;p<px;) ss[i++]=(*p++); ss[i++]='>'; if (exfm(i,ss,x->dsp)<0) diag(x,"default spec rejected",avv,588); ndo=|1; break; case TSFL: for (p=avv+1;p<px;p++) {x->flg[i=F(*p)]=1; if (i==(F'f')) fold(1); if (i==(F'k')) {x->kw0=x->kw1=(x->ocx)->kw1; for (i=0;i<128;i++) kwx[i]=0;};}; ndo=|1; break; case TRFL: for (p=avv+1;p<px;p++) {x->flg[i=F(*p)]=0; if (i==(F'f')) fold(0); if (i==(F'k')) index(x->kw0=(x->ocx)->kw1,x->kw1);}; ndo=|1; break; case TVFL: for (p=avv+1;p<px;p++) {i=F(*p); x->flg[i]=k=(x->ocx)->flg[i]; if (i==(F'f')) fold(k); if (i==(F'k')) index(x->kw0=(x->ocx)->kw0,x->kw1);}; ndo=|1; break; case TPKY: avv=+2; nv=- 2; if (pk=gtky(x,nv,avv)) {dfky(x,nv,avv,pk->nr,pk->rp); break;}; *px='='; write(getty(),avv,nv+1); px=(p=ss)+LNL; while (read(getty(),p,1)==1 && *p!='\n') {if (p<px) p++;}; px=p; p=ss; for (i=0;p<px;) {if ((k=0177&(*p++))=='\\') {if (p<px) k=0200|(*p++);}; ss[i++]=k;}; if ((k=hex(i,ss))>=0) {dfky(x,nv,avv,0,k); break;}; px=(p=ss)+i; while (p<px) *p++=0177&(*p); dfky(x,nv,avv,i,ss); break; case TDHX: dfky(x,nv-4,avv,0,vx); break; case TDKY: i=vx+1; dfky(x,vx,avv,nv-i,avv+i); break; case TCHD: if (x->dfl==0) {svdir(x->dsv,NDR); x->dfl++;}; if (chdir(avv+vx)<0) diag(x,"cannot chdir",avv+vx,589); break; case TEXC: avv++; nv--; if (xpipe(pd)<0) {p="(pipe)"; goto NC;}; if ((i=tfork())==(-1)) {p="(fork)"; NC: k=diag(x,"cannot run command",p,590); goto XC;}; if (i==0) {close(0); open("/dev/null",0); close(1); dup(pd[1]); execl("/bin/sh","sh","-c",avv,0); exit(040);}; close(pd[1]); ndo=|dofile(pd[0],avv,x,vt); k=shex(x); XC: if (k) putl(&dbf,nv,avv); break; case TFIL: ndo=|dofile(open(avv,0),avv,x,vt);}; return (ndo);}; type(n,s,xp) char *s; int *xp; {char *px; register int i,t; register char *p; i=s[0]; if (n<=0) return (TCOM); if (n==1) {if (i=='.') return (TEOF); if (i=='-') return (TINP); if (i=='+') return (TTTY);}; if (n>=2 && s[1]==':') {if (i=='-') return (TPIN); if (i=='+') return (TPTY); if (i=='=') return (TPKY);}; if (i==':') {if (n>=2 && s[n-1]==':') return (TFMT); return (TMSG);}; if (i=='!') {if (mtch(7,s,"!chdir ")) {for (i=7;i<n && s[i]==' ';i++); for (t=i;t<n && s[t]!=';';t++); if (t>=n) {*xp=i; return (TCHD);};}; return (TEXC);}; if (i=='$') return (TDOL); if (i=='~') return (TCOM); if (i=='-' || i=='+' || i=='=') {px=(p=s)+n; while (++p<px) {if ((t=(*p))>=0140) t=& 0137; if (t<'A' || t>'Z') break;}; if (p==px) {if (i=='-') return (TSFL); if (i=='+') return (TRFL); if (i=='=') return (TVFL);};}; p=s+n; while (--p>=s && *p!='='); i=p-s; if (i>=0) {t=i+1; t=hex(n-t,s+t); if (t>=0) {*xp=t; return (TDHX);}; *xp=i; return (TDKY);}; for (i=0;i<NHST;i++) {t=host[i].hcnt; if (n==t && mtch(t,s,host[i].hnam)!=0) {if (nhst<0) nhst=i; return (TCOM);};}; return (TFIL);}; hex(n,s) char *s; {register int i,h; register char *p; p=s; if (n!=3 || *p++!='^') return (-1); h=0; i=(*p++); if (i>=0140) i=& 0137; if (i>='0' && i<='9') h=+(i-'0'); else if (i>='A' && i<='F') h=+(i+10-'A'); else return (-1); h=<<4; i=(*p++); if (i>=0140) i=& 0137; if (i>='0' && i<='9') h=+(i-'0'); else if (i>='A' && i<='F') h=+(i+10-'A'); else return (-1); return (h);}; /*end*/