14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1982-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * David Korn 234887Schin * AT&T Labs 244887Schin * 254887Schin * shell intermediate code reader 264887Schin * 274887Schin */ 284887Schin 294887Schin #include <ccode.h> 304887Schin #include "defs.h" 314887Schin #include "shnodes.h" 324887Schin #include "path.h" 334887Schin #include "io.h" 344887Schin 35*8462SApril.Chin@Sun.COM static struct dolnod *r_comlist(Shell_t*); 36*8462SApril.Chin@Sun.COM static struct argnod *r_arg(Shell_t*); 37*8462SApril.Chin@Sun.COM static struct ionod *r_redirect(Shell_t*); 38*8462SApril.Chin@Sun.COM static struct regnod *r_switch(Shell_t*); 39*8462SApril.Chin@Sun.COM static Shnode_t *r_tree(Shell_t*); 40*8462SApril.Chin@Sun.COM static char *r_string(Stk_t*); 41*8462SApril.Chin@Sun.COM static void r_comarg(Shell_t*,struct comnod*); 424887Schin 434887Schin static Sfio_t *infile; 444887Schin 45*8462SApril.Chin@Sun.COM #define getnode(s,type) ((Shnode_t*)stkalloc((s),sizeof(struct type))) 464887Schin 47*8462SApril.Chin@Sun.COM Shnode_t *sh_trestore(Shell_t *shp,Sfio_t *in) 484887Schin { 494887Schin Shnode_t *t; 504887Schin infile = in; 51*8462SApril.Chin@Sun.COM t = r_tree(shp); 524887Schin return(t); 534887Schin } 544887Schin /* 554887Schin * read in a shell tree 564887Schin */ 57*8462SApril.Chin@Sun.COM static Shnode_t *r_tree(Shell_t *shp) 584887Schin { 594887Schin long l = sfgetl(infile); 604887Schin register int type; 614887Schin register Shnode_t *t=0; 624887Schin if(l<0) 634887Schin return(t); 644887Schin type = l; 654887Schin switch(type&COMMSK) 664887Schin { 674887Schin case TTIME: 684887Schin case TPAR: 69*8462SApril.Chin@Sun.COM t = getnode(shp->stk,parnod); 70*8462SApril.Chin@Sun.COM t->par.partre = r_tree(shp); 714887Schin break; 724887Schin case TCOM: 73*8462SApril.Chin@Sun.COM t = getnode(shp->stk,comnod); 744887Schin t->tre.tretyp = type; 75*8462SApril.Chin@Sun.COM r_comarg(shp,(struct comnod*)t); 764887Schin break; 774887Schin case TSETIO: 784887Schin case TFORK: 79*8462SApril.Chin@Sun.COM t = getnode(shp->stk,forknod); 804887Schin t->fork.forkline = sfgetu(infile); 81*8462SApril.Chin@Sun.COM t->fork.forktre = r_tree(shp); 82*8462SApril.Chin@Sun.COM t->fork.forkio = r_redirect(shp); 834887Schin break; 844887Schin case TIF: 85*8462SApril.Chin@Sun.COM t = getnode(shp->stk,ifnod); 86*8462SApril.Chin@Sun.COM t->if_.iftre = r_tree(shp); 87*8462SApril.Chin@Sun.COM t->if_.thtre = r_tree(shp); 88*8462SApril.Chin@Sun.COM t->if_.eltre = r_tree(shp); 894887Schin break; 904887Schin case TWH: 91*8462SApril.Chin@Sun.COM t = getnode(shp->stk,whnod); 92*8462SApril.Chin@Sun.COM t->wh.whinc = (struct arithnod*)r_tree(shp); 93*8462SApril.Chin@Sun.COM t->wh.whtre = r_tree(shp); 94*8462SApril.Chin@Sun.COM t->wh.dotre = r_tree(shp); 954887Schin break; 964887Schin case TLST: 974887Schin case TAND: 984887Schin case TORF: 994887Schin case TFIL: 100*8462SApril.Chin@Sun.COM t = getnode(shp->stk,lstnod); 101*8462SApril.Chin@Sun.COM t->lst.lstlef = r_tree(shp); 102*8462SApril.Chin@Sun.COM t->lst.lstrit = r_tree(shp); 1034887Schin break; 1044887Schin case TARITH: 105*8462SApril.Chin@Sun.COM t = getnode(shp->stk,arithnod); 1064887Schin t->ar.arline = sfgetu(infile); 107*8462SApril.Chin@Sun.COM t->ar.arexpr = r_arg(shp); 1084887Schin t->ar.arcomp = 0; 1094887Schin if((t->ar.arexpr)->argflag&ARG_RAW) 1104887Schin t->ar.arcomp = sh_arithcomp((t->ar.arexpr)->argval); 1114887Schin break; 1124887Schin case TFOR: 113*8462SApril.Chin@Sun.COM t = getnode(shp->stk,fornod); 1144887Schin t->for_.forline = 0; 1154887Schin if(type&FLINENO) 1164887Schin t->for_.forline = sfgetu(infile); 117*8462SApril.Chin@Sun.COM t->for_.fortre = r_tree(shp); 118*8462SApril.Chin@Sun.COM t->for_.fornam = r_string(shp->stk); 119*8462SApril.Chin@Sun.COM t->for_.forlst = (struct comnod*)r_tree(shp); 1204887Schin break; 1214887Schin case TSW: 122*8462SApril.Chin@Sun.COM t = getnode(shp->stk,swnod); 1234887Schin t->sw.swline = 0; 1244887Schin if(type&FLINENO) 1254887Schin t->sw.swline = sfgetu(infile); 126*8462SApril.Chin@Sun.COM t->sw.swarg = r_arg(shp); 1274887Schin if(type&COMSCAN) 128*8462SApril.Chin@Sun.COM t->sw.swio = r_redirect(shp); 1294887Schin else 1304887Schin t->sw.swio = 0; 131*8462SApril.Chin@Sun.COM t->sw.swlst = r_switch(shp); 1324887Schin break; 1334887Schin case TFUN: 1344887Schin { 1354887Schin Stak_t *savstak; 1364887Schin struct slnod *slp; 137*8462SApril.Chin@Sun.COM t = getnode(shp->stk,functnod); 1384887Schin t->funct.functloc = -1; 1394887Schin t->funct.functline = sfgetu(infile); 140*8462SApril.Chin@Sun.COM t->funct.functnam = r_string(shp->stk); 1414887Schin savstak = stakcreate(STAK_SMALL); 1424887Schin savstak = stakinstall(savstak, 0); 143*8462SApril.Chin@Sun.COM slp = (struct slnod*)stkalloc(shp->stk,sizeof(struct slnod)); 1444887Schin slp->slchild = 0; 145*8462SApril.Chin@Sun.COM slp->slnext = shp->st.staklist; 146*8462SApril.Chin@Sun.COM shp->st.staklist = 0; 147*8462SApril.Chin@Sun.COM t->funct.functtre = r_tree(shp); 1484887Schin t->funct.functstak = slp; 1494887Schin slp->slptr = stakinstall(savstak,0); 150*8462SApril.Chin@Sun.COM slp->slchild = shp->st.staklist; 151*8462SApril.Chin@Sun.COM t->funct.functargs = (struct comnod*)r_tree(shp); 1524887Schin break; 1534887Schin } 1544887Schin case TTST: 155*8462SApril.Chin@Sun.COM t = getnode(shp->stk,tstnod); 1564887Schin t->tst.tstline = sfgetu(infile); 1574887Schin if((type&TPAREN)==TPAREN) 158*8462SApril.Chin@Sun.COM t->lst.lstlef = r_tree(shp); 1594887Schin else 1604887Schin { 161*8462SApril.Chin@Sun.COM t->lst.lstlef = (Shnode_t*)r_arg(shp); 1624887Schin if((type&TBINARY)) 163*8462SApril.Chin@Sun.COM t->lst.lstrit = (Shnode_t*)r_arg(shp); 1644887Schin } 1654887Schin } 1664887Schin if(t) 1674887Schin t->tre.tretyp = type; 1684887Schin return(t); 1694887Schin } 1704887Schin 171*8462SApril.Chin@Sun.COM static struct argnod *r_arg(Shell_t *shp) 1724887Schin { 1734887Schin register struct argnod *ap=0, *apold, *aptop=0; 1744887Schin register long l; 175*8462SApril.Chin@Sun.COM Stk_t *stkp=shp->stk; 1764887Schin while((l=sfgetu(infile))>0) 1774887Schin { 178*8462SApril.Chin@Sun.COM ap = (struct argnod*)stkseek(stkp,(unsigned)l+ARGVAL); 1794887Schin if(!aptop) 1804887Schin aptop = ap; 1814887Schin else 1824887Schin apold->argnxt.ap = ap; 1834887Schin if(--l > 0) 1844887Schin { 1854887Schin sfread(infile,ap->argval,(size_t)l); 1864887Schin ccmaps(ap->argval, l, CC_ASCII, CC_NATIVE); 1874887Schin } 1884887Schin ap->argval[l] = 0; 1894887Schin ap->argchn.cp = 0; 1904887Schin ap->argflag = sfgetc(infile); 191*8462SApril.Chin@Sun.COM if((ap->argflag&ARG_MESSAGE) && *ap->argval) 1924887Schin { 1934887Schin /* replace international messages */ 194*8462SApril.Chin@Sun.COM ap = sh_endword(shp,1); 1954887Schin ap->argflag &= ~ARG_MESSAGE; 1964887Schin if(!(ap->argflag&(ARG_MAC|ARG_EXP))) 197*8462SApril.Chin@Sun.COM ap = sh_endword(shp,0); 1984887Schin else 1994887Schin { 200*8462SApril.Chin@Sun.COM ap = (struct argnod*)stkfreeze(stkp,0); 2014887Schin if(ap->argflag==0) 2024887Schin ap->argflag = ARG_RAW; 2034887Schin } 2044887Schin } 2054887Schin else 206*8462SApril.Chin@Sun.COM ap = (struct argnod*)stkfreeze(stkp,0); 207*8462SApril.Chin@Sun.COM if(*ap->argval==0 && (ap->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED))==0) 2084887Schin { 209*8462SApril.Chin@Sun.COM struct fornod *fp = (struct fornod*)getnode(shp->stk,fornod); 2104887Schin fp->fortyp = sfgetu(infile); 211*8462SApril.Chin@Sun.COM fp->fortre = r_tree(shp); 2124887Schin fp->fornam = ap->argval+1; 2134887Schin ap->argchn.ap = (struct argnod*)fp; 2144887Schin } 2154887Schin apold = ap; 2164887Schin } 2174887Schin if(ap) 2184887Schin ap->argnxt.ap = 0; 2194887Schin return(aptop); 2204887Schin } 2214887Schin 222*8462SApril.Chin@Sun.COM static struct ionod *r_redirect(Shell_t* shp) 2234887Schin { 2244887Schin register long l; 2254887Schin register struct ionod *iop=0, *iopold, *ioptop=0; 2264887Schin while((l=sfgetl(infile))>=0) 2274887Schin { 228*8462SApril.Chin@Sun.COM iop = (struct ionod*)getnode(shp->stk,ionod); 2294887Schin if(!ioptop) 2304887Schin ioptop = iop; 2314887Schin else 2324887Schin iopold->ionxt = iop; 2334887Schin iop->iofile = l; 234*8462SApril.Chin@Sun.COM iop->ioname = r_string(shp->stk); 235*8462SApril.Chin@Sun.COM if(iop->iodelim = r_string(shp->stk)) 2364887Schin { 2374887Schin iop->iosize = sfgetl(infile); 238*8462SApril.Chin@Sun.COM if(shp->heredocs) 239*8462SApril.Chin@Sun.COM iop->iooffset = sfseek(shp->heredocs,(off_t)0,SEEK_END); 2404887Schin else 2414887Schin { 242*8462SApril.Chin@Sun.COM shp->heredocs = sftmp(512); 2434887Schin iop->iooffset = 0; 2444887Schin } 245*8462SApril.Chin@Sun.COM sfmove(infile,shp->heredocs, iop->iosize, -1); 2464887Schin } 2474887Schin iopold = iop; 2484887Schin if(iop->iofile&IOVNM) 249*8462SApril.Chin@Sun.COM iop->iovname = r_string(shp->stk); 2504887Schin else 2514887Schin iop->iovname = 0; 2524887Schin iop->iofile &= ~IOVNM; 2534887Schin } 2544887Schin if(iop) 2554887Schin iop->ionxt = 0; 2564887Schin return(ioptop); 2574887Schin } 2584887Schin 259*8462SApril.Chin@Sun.COM static void r_comarg(Shell_t *shp,struct comnod *com) 2604887Schin { 2614887Schin char *cmdname=0; 262*8462SApril.Chin@Sun.COM com->comio = r_redirect(shp); 263*8462SApril.Chin@Sun.COM com->comset = r_arg(shp); 2644887Schin com->comstate = 0; 2654887Schin if(com->comtyp&COMSCAN) 2664887Schin { 267*8462SApril.Chin@Sun.COM com->comarg = r_arg(shp); 2684887Schin if(com->comarg->argflag==ARG_RAW) 2694887Schin cmdname = com->comarg->argval; 2704887Schin } 271*8462SApril.Chin@Sun.COM else if(com->comarg = (struct argnod*)r_comlist(shp)) 2724887Schin cmdname = ((struct dolnod*)(com->comarg))->dolval[ARG_SPARE]; 2734887Schin com->comline = sfgetu(infile); 2744887Schin com->comnamq = 0; 2754887Schin if(cmdname) 2764887Schin { 2774887Schin char *cp; 278*8462SApril.Chin@Sun.COM com->comnamp = (void*)nv_search(cmdname,shp->fun_tree,0); 2794887Schin if(com->comnamp && (cp =strrchr(cmdname+1,'.'))) 2804887Schin { 2814887Schin *cp = 0; 282*8462SApril.Chin@Sun.COM com->comnamp = (void*)nv_open(cmdname,shp->var_tree,NV_VARNAME|NV_NOADD|NV_NOARRAY); 2834887Schin *cp = '.'; 2844887Schin } 2854887Schin } 2864887Schin else 2874887Schin com->comnamp = 0; 2884887Schin } 2894887Schin 290*8462SApril.Chin@Sun.COM static struct dolnod *r_comlist(Shell_t *shp) 2914887Schin { 2924887Schin register struct dolnod *dol=0; 2934887Schin register long l; 2944887Schin register char **argv; 2954887Schin if((l=sfgetl(infile))>0) 2964887Schin { 297*8462SApril.Chin@Sun.COM dol = (struct dolnod*)stkalloc(shp->stk,sizeof(struct dolnod) + sizeof(char*)*(l+ARG_SPARE)); 2984887Schin dol->dolnum = l; 2994887Schin dol->dolbot = ARG_SPARE; 3004887Schin argv = dol->dolval+ARG_SPARE; 301*8462SApril.Chin@Sun.COM while(*argv++ = r_string(shp->stk)); 3024887Schin } 3034887Schin return(dol); 3044887Schin } 3054887Schin 306*8462SApril.Chin@Sun.COM static struct regnod *r_switch(Shell_t *shp) 3074887Schin { 3084887Schin register long l; 3094887Schin struct regnod *reg=0,*regold,*regtop=0; 3104887Schin while((l=sfgetl(infile))>=0) 3114887Schin { 312*8462SApril.Chin@Sun.COM reg = (struct regnod*)getnode(shp->stk,regnod); 3134887Schin if(!regtop) 3144887Schin regtop = reg; 3154887Schin else 3164887Schin regold->regnxt = reg; 3174887Schin reg->regflag = l; 318*8462SApril.Chin@Sun.COM reg->regptr = r_arg(shp); 319*8462SApril.Chin@Sun.COM reg->regcom = r_tree(shp); 3204887Schin regold = reg; 3214887Schin } 3224887Schin if(reg) 3234887Schin reg->regnxt = 0; 3244887Schin return(regtop); 3254887Schin } 3264887Schin 327*8462SApril.Chin@Sun.COM static char *r_string(Stk_t *stkp) 3284887Schin { 3294887Schin register Sfio_t *in = infile; 3304887Schin register unsigned long l = sfgetu(in); 3314887Schin register char *ptr; 3324887Schin if(l == 0) 3334887Schin return(NIL(char*)); 334*8462SApril.Chin@Sun.COM ptr = stkalloc(stkp,(unsigned)l); 3354887Schin if(--l > 0) 3364887Schin { 3374887Schin if(sfread(in,ptr,(size_t)l)!=(size_t)l) 3384887Schin return(NIL(char*)); 3394887Schin ccmaps(ptr, l, CC_ASCII, CC_NATIVE); 3404887Schin } 3414887Schin ptr[l] = 0; 3424887Schin return(ptr); 3434887Schin } 344