1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*0Sstevel@tonic-gate /* All Rights Reserved */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.10.4.1 */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate /* 29*0Sstevel@tonic-gate * UNIX shell 30*0Sstevel@tonic-gate */ 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include "defs.h" 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate static struct dolnod *copyargs(); 35*0Sstevel@tonic-gate static struct dolnod *freedolh(); 36*0Sstevel@tonic-gate extern struct dolnod *freeargs(); 37*0Sstevel@tonic-gate static struct dolnod *dolh; 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate /* Used to save outermost positional parameters */ 40*0Sstevel@tonic-gate static struct dolnod *globdolh; 41*0Sstevel@tonic-gate static unsigned char **globdolv; 42*0Sstevel@tonic-gate static int globdolc; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate unsigned char flagadr[16]; 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate unsigned char flagchar[] = 47*0Sstevel@tonic-gate { 48*0Sstevel@tonic-gate 'x', 49*0Sstevel@tonic-gate 'n', 50*0Sstevel@tonic-gate 'v', 51*0Sstevel@tonic-gate 't', 52*0Sstevel@tonic-gate STDFLG, 53*0Sstevel@tonic-gate 'i', 54*0Sstevel@tonic-gate 'e', 55*0Sstevel@tonic-gate 'r', 56*0Sstevel@tonic-gate 'k', 57*0Sstevel@tonic-gate 'u', 58*0Sstevel@tonic-gate 'h', 59*0Sstevel@tonic-gate 'f', 60*0Sstevel@tonic-gate 'a', 61*0Sstevel@tonic-gate 'm', 62*0Sstevel@tonic-gate 'p', 63*0Sstevel@tonic-gate 0 64*0Sstevel@tonic-gate }; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate long flagval[] = 67*0Sstevel@tonic-gate { 68*0Sstevel@tonic-gate execpr, 69*0Sstevel@tonic-gate noexec, 70*0Sstevel@tonic-gate readpr, 71*0Sstevel@tonic-gate oneflg, 72*0Sstevel@tonic-gate stdflg, 73*0Sstevel@tonic-gate intflg, 74*0Sstevel@tonic-gate errflg, 75*0Sstevel@tonic-gate rshflg, 76*0Sstevel@tonic-gate keyflg, 77*0Sstevel@tonic-gate setflg, 78*0Sstevel@tonic-gate hashflg, 79*0Sstevel@tonic-gate nofngflg, 80*0Sstevel@tonic-gate exportflg, 81*0Sstevel@tonic-gate monitorflg, 82*0Sstevel@tonic-gate privflg, 83*0Sstevel@tonic-gate 0 84*0Sstevel@tonic-gate }; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate /* ======== option handling ======== */ 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate options(argc,argv) 90*0Sstevel@tonic-gate unsigned char **argv; 91*0Sstevel@tonic-gate int argc; 92*0Sstevel@tonic-gate { 93*0Sstevel@tonic-gate register unsigned char *cp; 94*0Sstevel@tonic-gate register unsigned char **argp = argv; 95*0Sstevel@tonic-gate register unsigned char *flagc; 96*0Sstevel@tonic-gate unsigned char *flagp; 97*0Sstevel@tonic-gate int len; 98*0Sstevel@tonic-gate wchar_t wc; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate if (argc > 1 && *argp[1] == '-') 101*0Sstevel@tonic-gate { 102*0Sstevel@tonic-gate /* 103*0Sstevel@tonic-gate * if first argument is "--" then options are not 104*0Sstevel@tonic-gate * to be changed. Fix for problems getting 105*0Sstevel@tonic-gate * $1 starting with a "-" 106*0Sstevel@tonic-gate */ 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate cp = argp[1]; 109*0Sstevel@tonic-gate if (cp[1] == '-') 110*0Sstevel@tonic-gate { 111*0Sstevel@tonic-gate argp[1] = argp[0]; 112*0Sstevel@tonic-gate argc--; 113*0Sstevel@tonic-gate return(argc); 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate if (cp[1] == '\0') 116*0Sstevel@tonic-gate flags &= ~(execpr|readpr); 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* 119*0Sstevel@tonic-gate * Step along 'flagchar[]' looking for matches. 120*0Sstevel@tonic-gate * 'sicrp' are not legal with 'set' command. 121*0Sstevel@tonic-gate */ 122*0Sstevel@tonic-gate cp++; 123*0Sstevel@tonic-gate while (*cp) { 124*0Sstevel@tonic-gate if ((len = mbtowc(&wc, (char *)cp, MB_LEN_MAX)) <= 0) { 125*0Sstevel@tonic-gate len = 1; 126*0Sstevel@tonic-gate wc = (unsigned char)*cp; 127*0Sstevel@tonic-gate failed(argv[1],badopt); 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate cp += len; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate flagc = flagchar; 132*0Sstevel@tonic-gate while (*flagc && wc != *flagc) 133*0Sstevel@tonic-gate flagc++; 134*0Sstevel@tonic-gate if (wc == *flagc) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate if (eq(argv[0], "set") && any(wc, "sicrp")) 137*0Sstevel@tonic-gate failed(argv[1], badopt); 138*0Sstevel@tonic-gate else 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate flags |= flagval[flagc-flagchar]; 141*0Sstevel@tonic-gate if (flags & errflg) 142*0Sstevel@tonic-gate eflag = errflg; 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate else if (wc == 'c' && argc > 2 && comdiv == 0) 146*0Sstevel@tonic-gate { 147*0Sstevel@tonic-gate comdiv = argp[2]; 148*0Sstevel@tonic-gate argp[1] = argp[0]; 149*0Sstevel@tonic-gate argp++; 150*0Sstevel@tonic-gate argc--; 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate else 153*0Sstevel@tonic-gate failed(argv[1],badopt); 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate argp[1] = argp[0]; 156*0Sstevel@tonic-gate argc--; 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate else if (argc > 1 && *argp[1] == '+') /* unset flags x, k, t, n, v, e, u */ 159*0Sstevel@tonic-gate { 160*0Sstevel@tonic-gate cp = argp[1]; 161*0Sstevel@tonic-gate cp++; 162*0Sstevel@tonic-gate while (*cp) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate if ((len = mbtowc(&wc, (char *)cp, MB_LEN_MAX)) <= 0) { 165*0Sstevel@tonic-gate cp++; 166*0Sstevel@tonic-gate continue; 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate flagc = flagchar; 170*0Sstevel@tonic-gate while (*flagc && wc != *flagc) 171*0Sstevel@tonic-gate flagc++; 172*0Sstevel@tonic-gate /* 173*0Sstevel@tonic-gate * step through flags 174*0Sstevel@tonic-gate */ 175*0Sstevel@tonic-gate if (!any(wc, "sicrp") && wc == *flagc) { 176*0Sstevel@tonic-gate flags &= ~(flagval[flagc-flagchar]); 177*0Sstevel@tonic-gate if (wc == 'e') 178*0Sstevel@tonic-gate eflag = 0; 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate cp += len; 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate argp[1] = argp[0]; 183*0Sstevel@tonic-gate argc--; 184*0Sstevel@tonic-gate } 185*0Sstevel@tonic-gate /* 186*0Sstevel@tonic-gate * set up $- 187*0Sstevel@tonic-gate */ 188*0Sstevel@tonic-gate flagp = flagadr; 189*0Sstevel@tonic-gate if (flags) 190*0Sstevel@tonic-gate { 191*0Sstevel@tonic-gate flagc = flagchar; 192*0Sstevel@tonic-gate while (*flagc) 193*0Sstevel@tonic-gate { 194*0Sstevel@tonic-gate if (flags & flagval[flagc-flagchar]) 195*0Sstevel@tonic-gate *flagp++ = *flagc; 196*0Sstevel@tonic-gate flagc++; 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate *flagp = 0; 200*0Sstevel@tonic-gate return(argc); 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate /* 204*0Sstevel@tonic-gate * sets up positional parameters 205*0Sstevel@tonic-gate */ 206*0Sstevel@tonic-gate setargs(argi) 207*0Sstevel@tonic-gate unsigned char *argi[]; 208*0Sstevel@tonic-gate { 209*0Sstevel@tonic-gate register unsigned char **argp = argi; /* count args */ 210*0Sstevel@tonic-gate register int argn = 0; 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate while (*argp++ != (unsigned char *)ENDARGS) 213*0Sstevel@tonic-gate argn++; 214*0Sstevel@tonic-gate /* 215*0Sstevel@tonic-gate * free old ones unless on for loop chain 216*0Sstevel@tonic-gate */ 217*0Sstevel@tonic-gate freedolh(); 218*0Sstevel@tonic-gate dolh = copyargs(argi, argn); 219*0Sstevel@tonic-gate dolc = argn - 1; 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate static struct dolnod * 224*0Sstevel@tonic-gate freedolh() 225*0Sstevel@tonic-gate { 226*0Sstevel@tonic-gate register unsigned char **argp; 227*0Sstevel@tonic-gate register struct dolnod *argblk; 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate if (argblk = dolh) 230*0Sstevel@tonic-gate { 231*0Sstevel@tonic-gate if ((--argblk->doluse) == 0) 232*0Sstevel@tonic-gate { 233*0Sstevel@tonic-gate for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++) 234*0Sstevel@tonic-gate free(*argp); 235*0Sstevel@tonic-gate free(argblk->dolarg); 236*0Sstevel@tonic-gate free(argblk); 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate struct dolnod * 242*0Sstevel@tonic-gate freeargs(blk) 243*0Sstevel@tonic-gate struct dolnod *blk; 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate register unsigned char **argp; 246*0Sstevel@tonic-gate register struct dolnod *argr = 0; 247*0Sstevel@tonic-gate register struct dolnod *argblk; 248*0Sstevel@tonic-gate int cnt; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate if (argblk = blk) 251*0Sstevel@tonic-gate { 252*0Sstevel@tonic-gate argr = argblk->dolnxt; 253*0Sstevel@tonic-gate cnt = --argblk->doluse; 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate if (argblk == dolh) 256*0Sstevel@tonic-gate { 257*0Sstevel@tonic-gate if (cnt == 1) 258*0Sstevel@tonic-gate return(argr); 259*0Sstevel@tonic-gate else 260*0Sstevel@tonic-gate return(argblk); 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate else 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate if (cnt == 0) 265*0Sstevel@tonic-gate { 266*0Sstevel@tonic-gate for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++) 267*0Sstevel@tonic-gate free(*argp); 268*0Sstevel@tonic-gate free(argblk->dolarg); 269*0Sstevel@tonic-gate free(argblk); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate } 273*0Sstevel@tonic-gate return(argr); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate static struct dolnod * 277*0Sstevel@tonic-gate copyargs(from, n) 278*0Sstevel@tonic-gate unsigned char *from[]; 279*0Sstevel@tonic-gate { 280*0Sstevel@tonic-gate register struct dolnod *np = (struct dolnod *)alloc(sizeof(struct dolnod)); 281*0Sstevel@tonic-gate register unsigned char **fp = from; 282*0Sstevel@tonic-gate register unsigned char **pp; 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate np -> dolnxt = 0; 285*0Sstevel@tonic-gate np->doluse = 1; /* use count */ 286*0Sstevel@tonic-gate pp = np->dolarg = (unsigned char **)alloc((n+1)*sizeof(char *)); 287*0Sstevel@tonic-gate dolv = pp; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate while (n--) 290*0Sstevel@tonic-gate *pp++ = make(*fp++); 291*0Sstevel@tonic-gate *pp++ = ENDARGS; 292*0Sstevel@tonic-gate return(np); 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate struct dolnod * 297*0Sstevel@tonic-gate clean_args(blk) 298*0Sstevel@tonic-gate struct dolnod *blk; 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate register unsigned char **argp; 301*0Sstevel@tonic-gate register struct dolnod *argr = 0; 302*0Sstevel@tonic-gate register struct dolnod *argblk; 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate if (argblk = blk) 305*0Sstevel@tonic-gate { 306*0Sstevel@tonic-gate argr = argblk->dolnxt; 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate if (argblk == dolh) 309*0Sstevel@tonic-gate argblk->doluse = 1; 310*0Sstevel@tonic-gate else 311*0Sstevel@tonic-gate { 312*0Sstevel@tonic-gate for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++) 313*0Sstevel@tonic-gate free(*argp); 314*0Sstevel@tonic-gate free(argblk->dolarg); 315*0Sstevel@tonic-gate free(argblk); 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate return(argr); 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate clearup() 322*0Sstevel@tonic-gate { 323*0Sstevel@tonic-gate /* 324*0Sstevel@tonic-gate * force `for' $* lists to go away 325*0Sstevel@tonic-gate */ 326*0Sstevel@tonic-gate if(globdolv) 327*0Sstevel@tonic-gate dolv = globdolv; 328*0Sstevel@tonic-gate if(globdolc) 329*0Sstevel@tonic-gate dolc = globdolc; 330*0Sstevel@tonic-gate if(globdolh) 331*0Sstevel@tonic-gate dolh = globdolh; 332*0Sstevel@tonic-gate globdolv = 0; 333*0Sstevel@tonic-gate globdolc = 0; 334*0Sstevel@tonic-gate globdolh = 0; 335*0Sstevel@tonic-gate while (argfor = clean_args(argfor)) 336*0Sstevel@tonic-gate ; 337*0Sstevel@tonic-gate /* 338*0Sstevel@tonic-gate * clean up io files 339*0Sstevel@tonic-gate */ 340*0Sstevel@tonic-gate while (pop()) 341*0Sstevel@tonic-gate ; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate /* 344*0Sstevel@tonic-gate * Clean up pipe file descriptor 345*0Sstevel@tonic-gate * from command substitution 346*0Sstevel@tonic-gate */ 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate if(savpipe != -1) { 349*0Sstevel@tonic-gate close(savpipe); 350*0Sstevel@tonic-gate savpipe = -1; 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate /* 354*0Sstevel@tonic-gate * clean up tmp files 355*0Sstevel@tonic-gate */ 356*0Sstevel@tonic-gate while (poptemp()) 357*0Sstevel@tonic-gate ; 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate /* 361*0Sstevel@tonic-gate * Save positiional parameters before outermost function invocation 362*0Sstevel@tonic-gate * in case we are interrupted. 363*0Sstevel@tonic-gate * Increment use count for current positional parameters so that they aren't thrown 364*0Sstevel@tonic-gate * away. 365*0Sstevel@tonic-gate */ 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate struct dolnod *savargs(funcnt) 368*0Sstevel@tonic-gate int funcnt; 369*0Sstevel@tonic-gate { 370*0Sstevel@tonic-gate if (!funcnt) { 371*0Sstevel@tonic-gate globdolh = dolh; 372*0Sstevel@tonic-gate globdolv = dolv; 373*0Sstevel@tonic-gate globdolc = dolc; 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate useargs(); 376*0Sstevel@tonic-gate return(dolh); 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate /* After function invocation, free positional parameters, 380*0Sstevel@tonic-gate * restore old positional parameters, and restore 381*0Sstevel@tonic-gate * use count. 382*0Sstevel@tonic-gate */ 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate void restorargs(olddolh, funcnt) 385*0Sstevel@tonic-gate struct dolnod *olddolh; 386*0Sstevel@tonic-gate { 387*0Sstevel@tonic-gate if(argfor != olddolh) 388*0Sstevel@tonic-gate while ((argfor = clean_args(argfor)) != olddolh && argfor); 389*0Sstevel@tonic-gate if(!argfor) 390*0Sstevel@tonic-gate return; 391*0Sstevel@tonic-gate freedolh(); 392*0Sstevel@tonic-gate dolh = olddolh; 393*0Sstevel@tonic-gate if(dolh) 394*0Sstevel@tonic-gate dolh -> doluse++; /* increment use count so arguments aren't freed */ 395*0Sstevel@tonic-gate argfor = freeargs(dolh); 396*0Sstevel@tonic-gate if(funcnt == 1) { 397*0Sstevel@tonic-gate globdolh = 0; 398*0Sstevel@tonic-gate globdolv = 0; 399*0Sstevel@tonic-gate globdolc = 0; 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate } 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate struct dolnod * 404*0Sstevel@tonic-gate useargs() 405*0Sstevel@tonic-gate { 406*0Sstevel@tonic-gate if (dolh) 407*0Sstevel@tonic-gate { 408*0Sstevel@tonic-gate if (dolh->doluse++ == 1) 409*0Sstevel@tonic-gate { 410*0Sstevel@tonic-gate dolh->dolnxt = argfor; 411*0Sstevel@tonic-gate argfor = dolh; 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate return(dolh); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate 417