1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * UNIX shell 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include "defs.h" 37*7c478bd9Sstevel@tonic-gate #include <stropts.h> 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate extern BOOL chkid(); 40*7c478bd9Sstevel@tonic-gate extern unsigned char *simple(); 41*7c478bd9Sstevel@tonic-gate extern int mailchk; 42*7c478bd9Sstevel@tonic-gate static void namwalk(); 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static void set_builtins_path(); 45*7c478bd9Sstevel@tonic-gate static int patheq(); 46*7c478bd9Sstevel@tonic-gate static void dolocale(); 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate struct namnod ps2nod = 49*7c478bd9Sstevel@tonic-gate { 50*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 51*7c478bd9Sstevel@tonic-gate &acctnod, 52*7c478bd9Sstevel@tonic-gate (unsigned char *)ps2name 53*7c478bd9Sstevel@tonic-gate }; 54*7c478bd9Sstevel@tonic-gate struct namnod cdpnod = 55*7c478bd9Sstevel@tonic-gate { 56*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 57*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 58*7c478bd9Sstevel@tonic-gate (unsigned char *)cdpname 59*7c478bd9Sstevel@tonic-gate }; 60*7c478bd9Sstevel@tonic-gate struct namnod pathnod = 61*7c478bd9Sstevel@tonic-gate { 62*7c478bd9Sstevel@tonic-gate &mailpnod, 63*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 64*7c478bd9Sstevel@tonic-gate (unsigned char *)pathname 65*7c478bd9Sstevel@tonic-gate }; 66*7c478bd9Sstevel@tonic-gate struct namnod ifsnod = 67*7c478bd9Sstevel@tonic-gate { 68*7c478bd9Sstevel@tonic-gate &homenod, 69*7c478bd9Sstevel@tonic-gate &mailnod, 70*7c478bd9Sstevel@tonic-gate (unsigned char *)ifsname 71*7c478bd9Sstevel@tonic-gate }; 72*7c478bd9Sstevel@tonic-gate struct namnod ps1nod = 73*7c478bd9Sstevel@tonic-gate { 74*7c478bd9Sstevel@tonic-gate &pathnod, 75*7c478bd9Sstevel@tonic-gate &ps2nod, 76*7c478bd9Sstevel@tonic-gate (unsigned char *)ps1name 77*7c478bd9Sstevel@tonic-gate }; 78*7c478bd9Sstevel@tonic-gate struct namnod homenod = 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate &cdpnod, 81*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 82*7c478bd9Sstevel@tonic-gate (unsigned char *)homename 83*7c478bd9Sstevel@tonic-gate }; 84*7c478bd9Sstevel@tonic-gate struct namnod mailnod = 85*7c478bd9Sstevel@tonic-gate { 86*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 87*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 88*7c478bd9Sstevel@tonic-gate (unsigned char *)mailname 89*7c478bd9Sstevel@tonic-gate }; 90*7c478bd9Sstevel@tonic-gate struct namnod mchknod = 91*7c478bd9Sstevel@tonic-gate { 92*7c478bd9Sstevel@tonic-gate &ifsnod, 93*7c478bd9Sstevel@tonic-gate &ps1nod, 94*7c478bd9Sstevel@tonic-gate (unsigned char *)mchkname 95*7c478bd9Sstevel@tonic-gate }; 96*7c478bd9Sstevel@tonic-gate struct namnod acctnod = 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 99*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 100*7c478bd9Sstevel@tonic-gate (unsigned char *)acctname 101*7c478bd9Sstevel@tonic-gate }; 102*7c478bd9Sstevel@tonic-gate struct namnod mailpnod = 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 105*7c478bd9Sstevel@tonic-gate (struct namnod *)NIL, 106*7c478bd9Sstevel@tonic-gate (unsigned char *)mailpname 107*7c478bd9Sstevel@tonic-gate }; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate struct namnod *namep = &mchknod; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* ======== variable and string handling ======== */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate syslook(w, syswds, n) 115*7c478bd9Sstevel@tonic-gate register unsigned char *w; 116*7c478bd9Sstevel@tonic-gate register struct sysnod syswds[]; 117*7c478bd9Sstevel@tonic-gate int n; 118*7c478bd9Sstevel@tonic-gate { 119*7c478bd9Sstevel@tonic-gate int low; 120*7c478bd9Sstevel@tonic-gate int high; 121*7c478bd9Sstevel@tonic-gate int mid; 122*7c478bd9Sstevel@tonic-gate register int cond; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate if (w == 0 || *w == 0) 125*7c478bd9Sstevel@tonic-gate return(0); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate low = 0; 128*7c478bd9Sstevel@tonic-gate high = n - 1; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate while (low <= high) 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate mid = (low + high) / 2; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate if ((cond = cf(w, syswds[mid].sysnam)) < 0) 135*7c478bd9Sstevel@tonic-gate high = mid - 1; 136*7c478bd9Sstevel@tonic-gate else if (cond > 0) 137*7c478bd9Sstevel@tonic-gate low = mid + 1; 138*7c478bd9Sstevel@tonic-gate else 139*7c478bd9Sstevel@tonic-gate return(syswds[mid].sysval); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate return(0); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate setlist(arg, xp) 145*7c478bd9Sstevel@tonic-gate register struct argnod *arg; 146*7c478bd9Sstevel@tonic-gate int xp; 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate if (flags & exportflg) 149*7c478bd9Sstevel@tonic-gate xp |= N_EXPORT; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate while (arg) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate register unsigned char *s = mactrim(arg->argval); 154*7c478bd9Sstevel@tonic-gate setname(s, xp); 155*7c478bd9Sstevel@tonic-gate arg = arg->argnxt; 156*7c478bd9Sstevel@tonic-gate if (flags & execpr) 157*7c478bd9Sstevel@tonic-gate { 158*7c478bd9Sstevel@tonic-gate prs(s); 159*7c478bd9Sstevel@tonic-gate if (arg) 160*7c478bd9Sstevel@tonic-gate blank(); 161*7c478bd9Sstevel@tonic-gate else 162*7c478bd9Sstevel@tonic-gate newline(); 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate setname(argi, xp) /* does parameter assignments */ 169*7c478bd9Sstevel@tonic-gate unsigned char *argi; 170*7c478bd9Sstevel@tonic-gate int xp; 171*7c478bd9Sstevel@tonic-gate { 172*7c478bd9Sstevel@tonic-gate register unsigned char *argscan = argi; 173*7c478bd9Sstevel@tonic-gate register struct namnod *n; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if (letter(*argscan)) 176*7c478bd9Sstevel@tonic-gate { 177*7c478bd9Sstevel@tonic-gate while (alphanum(*argscan)) 178*7c478bd9Sstevel@tonic-gate argscan++; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate if (*argscan == '=') 181*7c478bd9Sstevel@tonic-gate { 182*7c478bd9Sstevel@tonic-gate *argscan = 0; /* make name a cohesive string */ 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate n = lookup(argi); 185*7c478bd9Sstevel@tonic-gate *argscan++ = '='; 186*7c478bd9Sstevel@tonic-gate attrib(n, xp); 187*7c478bd9Sstevel@tonic-gate if (xp & N_ENVNAM) 188*7c478bd9Sstevel@tonic-gate { 189*7c478bd9Sstevel@tonic-gate n->namenv = n->namval = argscan; 190*7c478bd9Sstevel@tonic-gate if (n == &pathnod) 191*7c478bd9Sstevel@tonic-gate set_builtins_path(); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate else 194*7c478bd9Sstevel@tonic-gate assign(n, argscan); 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate dolocale(n->namid); 197*7c478bd9Sstevel@tonic-gate return; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate replace(a, v) 203*7c478bd9Sstevel@tonic-gate register unsigned char **a; 204*7c478bd9Sstevel@tonic-gate unsigned char *v; 205*7c478bd9Sstevel@tonic-gate { 206*7c478bd9Sstevel@tonic-gate free(*a); 207*7c478bd9Sstevel@tonic-gate *a = make(v); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate dfault(n, v) 211*7c478bd9Sstevel@tonic-gate struct namnod *n; 212*7c478bd9Sstevel@tonic-gate unsigned char *v; 213*7c478bd9Sstevel@tonic-gate { 214*7c478bd9Sstevel@tonic-gate if (n->namval == 0) 215*7c478bd9Sstevel@tonic-gate assign(n, v); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate assign(n, v) 219*7c478bd9Sstevel@tonic-gate struct namnod *n; 220*7c478bd9Sstevel@tonic-gate unsigned char *v; 221*7c478bd9Sstevel@tonic-gate { 222*7c478bd9Sstevel@tonic-gate if (n->namflg & N_RDONLY) 223*7c478bd9Sstevel@tonic-gate failed(n->namid, wtfailed); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate #ifndef RES 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate else if (flags & rshflg) 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate if (n == &pathnod || eq(n->namid,"SHELL")) 230*7c478bd9Sstevel@tonic-gate failed(n->namid, restricted); 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate #endif 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate else if (n->namflg & N_FUNCTN) 235*7c478bd9Sstevel@tonic-gate { 236*7c478bd9Sstevel@tonic-gate func_unhash(n->namid); 237*7c478bd9Sstevel@tonic-gate freefunc(n); 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate n->namenv = 0; 240*7c478bd9Sstevel@tonic-gate n->namflg = N_DEFAULT; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate if (n == &mchknod) 244*7c478bd9Sstevel@tonic-gate { 245*7c478bd9Sstevel@tonic-gate mailchk = stoi(v); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate replace(&n->namval, v); 249*7c478bd9Sstevel@tonic-gate attrib(n, N_ENVCHG); 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate if (n == &pathnod) 252*7c478bd9Sstevel@tonic-gate { 253*7c478bd9Sstevel@tonic-gate zaphash(); 254*7c478bd9Sstevel@tonic-gate set_dotpath(); 255*7c478bd9Sstevel@tonic-gate set_builtins_path(); 256*7c478bd9Sstevel@tonic-gate return; 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate if (flags & prompt) 260*7c478bd9Sstevel@tonic-gate { 261*7c478bd9Sstevel@tonic-gate if ((n == &mailpnod) || (n == &mailnod && mailpnod.namflg == N_DEFAULT)) 262*7c478bd9Sstevel@tonic-gate setmail(n->namval); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate static void 267*7c478bd9Sstevel@tonic-gate set_builtins_path() 268*7c478bd9Sstevel@tonic-gate { 269*7c478bd9Sstevel@tonic-gate register unsigned char *path; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate ucb_builtins = 0; 272*7c478bd9Sstevel@tonic-gate path = getpath(""); 273*7c478bd9Sstevel@tonic-gate while (path && *path) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate if (patheq(path, "/usr/ucb")) 276*7c478bd9Sstevel@tonic-gate { 277*7c478bd9Sstevel@tonic-gate ucb_builtins++; 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate else if (patheq(path, "/usr/bin")) 281*7c478bd9Sstevel@tonic-gate break; 282*7c478bd9Sstevel@tonic-gate else if (patheq(path, "/bin")) 283*7c478bd9Sstevel@tonic-gate break; 284*7c478bd9Sstevel@tonic-gate else if (patheq(path, "/usr/5bin")) 285*7c478bd9Sstevel@tonic-gate break; 286*7c478bd9Sstevel@tonic-gate path = nextpath(path); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate static int 291*7c478bd9Sstevel@tonic-gate patheq(component, dir) 292*7c478bd9Sstevel@tonic-gate register unsigned char *component; 293*7c478bd9Sstevel@tonic-gate register char *dir; 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate register unsigned char c; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate for (;;) 298*7c478bd9Sstevel@tonic-gate { 299*7c478bd9Sstevel@tonic-gate c = *component++; 300*7c478bd9Sstevel@tonic-gate if (c == COLON) 301*7c478bd9Sstevel@tonic-gate c = '\0'; /* end of component of path */ 302*7c478bd9Sstevel@tonic-gate if (c != *dir++) 303*7c478bd9Sstevel@tonic-gate return(0); 304*7c478bd9Sstevel@tonic-gate if (c == '\0') 305*7c478bd9Sstevel@tonic-gate return(1); 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate readvar(names) 310*7c478bd9Sstevel@tonic-gate unsigned char **names; 311*7c478bd9Sstevel@tonic-gate { 312*7c478bd9Sstevel@tonic-gate struct fileblk fb; 313*7c478bd9Sstevel@tonic-gate register struct fileblk *f = &fb; 314*7c478bd9Sstevel@tonic-gate unsigned char c[MULTI_BYTE_MAX+1]; 315*7c478bd9Sstevel@tonic-gate register int rc = 0; 316*7c478bd9Sstevel@tonic-gate struct namnod *n = lookup(*names++); /* done now to avoid storage mess */ 317*7c478bd9Sstevel@tonic-gate unsigned char *rel = (unsigned char *)relstak(); 318*7c478bd9Sstevel@tonic-gate unsigned char *oldstak; 319*7c478bd9Sstevel@tonic-gate register unsigned char *pc, *rest; 320*7c478bd9Sstevel@tonic-gate int d; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate push(f); 323*7c478bd9Sstevel@tonic-gate initf(dup(0)); 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* 326*7c478bd9Sstevel@tonic-gate * If stdin is a pipe then this lseek(2) will fail with ESPIPE, so 327*7c478bd9Sstevel@tonic-gate * the read buffer size is set to 1 because we will not be able 328*7c478bd9Sstevel@tonic-gate * lseek(2) back towards the beginning of the file, so we have 329*7c478bd9Sstevel@tonic-gate * to read a byte at a time instead 330*7c478bd9Sstevel@tonic-gate * 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate if (lseek(0, (off_t)0, SEEK_CUR) == -1) 333*7c478bd9Sstevel@tonic-gate f->fsiz = 1; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* 336*7c478bd9Sstevel@tonic-gate * If stdin is a socket then this isastream(3C) will return 1, so 337*7c478bd9Sstevel@tonic-gate * the read buffer size is set to 1 because we will not be able 338*7c478bd9Sstevel@tonic-gate * lseek(2) back towards the beginning of the file, so we have 339*7c478bd9Sstevel@tonic-gate * to read a byte at a time instead 340*7c478bd9Sstevel@tonic-gate * 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate if (isastream(0) == 1) 343*7c478bd9Sstevel@tonic-gate f->fsiz = 1; 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * strip leading IFS characters 347*7c478bd9Sstevel@tonic-gate */ 348*7c478bd9Sstevel@tonic-gate for (;;) 349*7c478bd9Sstevel@tonic-gate { 350*7c478bd9Sstevel@tonic-gate d = nextwc(); 351*7c478bd9Sstevel@tonic-gate if(eolchar(d)) 352*7c478bd9Sstevel@tonic-gate break; 353*7c478bd9Sstevel@tonic-gate rest = readw(d); 354*7c478bd9Sstevel@tonic-gate pc = c; 355*7c478bd9Sstevel@tonic-gate while(*pc++ = *rest++); 356*7c478bd9Sstevel@tonic-gate if(!anys(c, ifsnod.namval)) 357*7c478bd9Sstevel@tonic-gate break; 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate oldstak = curstak(); 361*7c478bd9Sstevel@tonic-gate for (;;) 362*7c478bd9Sstevel@tonic-gate { 363*7c478bd9Sstevel@tonic-gate if ((*names && anys(c, ifsnod.namval)) || eolchar(d)) 364*7c478bd9Sstevel@tonic-gate { 365*7c478bd9Sstevel@tonic-gate if (staktop >= brkend) 366*7c478bd9Sstevel@tonic-gate growstak(staktop); 367*7c478bd9Sstevel@tonic-gate zerostak(); 368*7c478bd9Sstevel@tonic-gate assign(n, absstak(rel)); 369*7c478bd9Sstevel@tonic-gate setstak(rel); 370*7c478bd9Sstevel@tonic-gate if (*names) 371*7c478bd9Sstevel@tonic-gate n = lookup(*names++); 372*7c478bd9Sstevel@tonic-gate else 373*7c478bd9Sstevel@tonic-gate n = 0; 374*7c478bd9Sstevel@tonic-gate if (eolchar(d)) 375*7c478bd9Sstevel@tonic-gate { 376*7c478bd9Sstevel@tonic-gate break; 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate else /* strip imbedded IFS characters */ 379*7c478bd9Sstevel@tonic-gate while(1) { 380*7c478bd9Sstevel@tonic-gate d = nextwc(); 381*7c478bd9Sstevel@tonic-gate if(eolchar(d)) 382*7c478bd9Sstevel@tonic-gate break; 383*7c478bd9Sstevel@tonic-gate rest = readw(d); 384*7c478bd9Sstevel@tonic-gate pc = c; 385*7c478bd9Sstevel@tonic-gate while(*pc++ = *rest++); 386*7c478bd9Sstevel@tonic-gate if(!anys(c, ifsnod.namval)) 387*7c478bd9Sstevel@tonic-gate break; 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate else 391*7c478bd9Sstevel@tonic-gate { 392*7c478bd9Sstevel@tonic-gate if(d == '\\') { 393*7c478bd9Sstevel@tonic-gate d = readwc(); 394*7c478bd9Sstevel@tonic-gate rest = readw(d); 395*7c478bd9Sstevel@tonic-gate while(d = *rest++) { 396*7c478bd9Sstevel@tonic-gate if (staktop >= brkend) 397*7c478bd9Sstevel@tonic-gate growstak(staktop); 398*7c478bd9Sstevel@tonic-gate pushstak(d); 399*7c478bd9Sstevel@tonic-gate } 400*7c478bd9Sstevel@tonic-gate oldstak = staktop; 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate else 403*7c478bd9Sstevel@tonic-gate { 404*7c478bd9Sstevel@tonic-gate pc = c; 405*7c478bd9Sstevel@tonic-gate while(d = *pc++) { 406*7c478bd9Sstevel@tonic-gate if (staktop >= brkend) 407*7c478bd9Sstevel@tonic-gate growstak(staktop); 408*7c478bd9Sstevel@tonic-gate pushstak(d); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate if(!anys(c, ifsnod.namval)) 411*7c478bd9Sstevel@tonic-gate oldstak = staktop; 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate d = nextwc(); 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (eolchar(d)) 416*7c478bd9Sstevel@tonic-gate staktop = oldstak; 417*7c478bd9Sstevel@tonic-gate else 418*7c478bd9Sstevel@tonic-gate { 419*7c478bd9Sstevel@tonic-gate rest = readw(d); 420*7c478bd9Sstevel@tonic-gate pc = c; 421*7c478bd9Sstevel@tonic-gate while(*pc++ = *rest++); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate while (n) 426*7c478bd9Sstevel@tonic-gate { 427*7c478bd9Sstevel@tonic-gate assign(n, nullstr); 428*7c478bd9Sstevel@tonic-gate if (*names) 429*7c478bd9Sstevel@tonic-gate n = lookup(*names++); 430*7c478bd9Sstevel@tonic-gate else 431*7c478bd9Sstevel@tonic-gate n = 0; 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate if (eof) 435*7c478bd9Sstevel@tonic-gate rc = 1; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate if (isastream(0) != 1) 438*7c478bd9Sstevel@tonic-gate /* 439*7c478bd9Sstevel@tonic-gate * If we are reading on a stream do not attempt to 440*7c478bd9Sstevel@tonic-gate * lseek(2) back towards the start because this is 441*7c478bd9Sstevel@tonic-gate * logically meaningless, but there is nothing in 442*7c478bd9Sstevel@tonic-gate * the standards to pervent the stream implementation 443*7c478bd9Sstevel@tonic-gate * from attempting it and breaking our code here 444*7c478bd9Sstevel@tonic-gate * 445*7c478bd9Sstevel@tonic-gate */ 446*7c478bd9Sstevel@tonic-gate lseek(0, (off_t)(f->nxtoff - f->endoff), SEEK_CUR); 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate pop(); 449*7c478bd9Sstevel@tonic-gate return(rc); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate assnum(p, i) 453*7c478bd9Sstevel@tonic-gate unsigned char **p; 454*7c478bd9Sstevel@tonic-gate long i; 455*7c478bd9Sstevel@tonic-gate { 456*7c478bd9Sstevel@tonic-gate int j = ltos(i); 457*7c478bd9Sstevel@tonic-gate replace(p, &numbuf[j]); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate unsigned char * 461*7c478bd9Sstevel@tonic-gate make(v) 462*7c478bd9Sstevel@tonic-gate unsigned char *v; 463*7c478bd9Sstevel@tonic-gate { 464*7c478bd9Sstevel@tonic-gate register unsigned char *p; 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate if (v) 467*7c478bd9Sstevel@tonic-gate { 468*7c478bd9Sstevel@tonic-gate movstr(v, p = (unsigned char *)alloc(length(v))); 469*7c478bd9Sstevel@tonic-gate return(p); 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate else 472*7c478bd9Sstevel@tonic-gate return(0); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate struct namnod * 477*7c478bd9Sstevel@tonic-gate lookup(nam) 478*7c478bd9Sstevel@tonic-gate register unsigned char *nam; 479*7c478bd9Sstevel@tonic-gate { 480*7c478bd9Sstevel@tonic-gate register struct namnod *nscan = namep; 481*7c478bd9Sstevel@tonic-gate register struct namnod **prev; 482*7c478bd9Sstevel@tonic-gate int LR; 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate if (!chkid(nam)) 485*7c478bd9Sstevel@tonic-gate failed(nam, notid); 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate while (nscan) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate if ((LR = cf(nam, nscan->namid)) == 0) 490*7c478bd9Sstevel@tonic-gate return(nscan); 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate else if (LR < 0) 493*7c478bd9Sstevel@tonic-gate prev = &(nscan->namlft); 494*7c478bd9Sstevel@tonic-gate else 495*7c478bd9Sstevel@tonic-gate prev = &(nscan->namrgt); 496*7c478bd9Sstevel@tonic-gate nscan = *prev; 497*7c478bd9Sstevel@tonic-gate } 498*7c478bd9Sstevel@tonic-gate /* 499*7c478bd9Sstevel@tonic-gate * add name node 500*7c478bd9Sstevel@tonic-gate */ 501*7c478bd9Sstevel@tonic-gate nscan = (struct namnod *)alloc(sizeof *nscan); 502*7c478bd9Sstevel@tonic-gate nscan->namlft = nscan->namrgt = (struct namnod *)NIL; 503*7c478bd9Sstevel@tonic-gate nscan->namid = make(nam); 504*7c478bd9Sstevel@tonic-gate nscan->namval = 0; 505*7c478bd9Sstevel@tonic-gate nscan->namflg = N_DEFAULT; 506*7c478bd9Sstevel@tonic-gate nscan->namenv = 0; 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate return(*prev = nscan); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate BOOL 512*7c478bd9Sstevel@tonic-gate chkid(nam) 513*7c478bd9Sstevel@tonic-gate unsigned char *nam; 514*7c478bd9Sstevel@tonic-gate { 515*7c478bd9Sstevel@tonic-gate register unsigned char *cp = nam; 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate if (!letter(*cp)) 518*7c478bd9Sstevel@tonic-gate return(FALSE); 519*7c478bd9Sstevel@tonic-gate else 520*7c478bd9Sstevel@tonic-gate { 521*7c478bd9Sstevel@tonic-gate while (*++cp) 522*7c478bd9Sstevel@tonic-gate { 523*7c478bd9Sstevel@tonic-gate if (!alphanum(*cp)) 524*7c478bd9Sstevel@tonic-gate return(FALSE); 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate return(TRUE); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate static int (*namfn)(); 531*7c478bd9Sstevel@tonic-gate namscan(fn) 532*7c478bd9Sstevel@tonic-gate int (*fn)(); 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate namfn = fn; 535*7c478bd9Sstevel@tonic-gate namwalk(namep); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate static void 539*7c478bd9Sstevel@tonic-gate namwalk(np) 540*7c478bd9Sstevel@tonic-gate register struct namnod *np; 541*7c478bd9Sstevel@tonic-gate { 542*7c478bd9Sstevel@tonic-gate if (np) 543*7c478bd9Sstevel@tonic-gate { 544*7c478bd9Sstevel@tonic-gate namwalk(np->namlft); 545*7c478bd9Sstevel@tonic-gate (*namfn)(np); 546*7c478bd9Sstevel@tonic-gate namwalk(np->namrgt); 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate } 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate printnam(n) 551*7c478bd9Sstevel@tonic-gate struct namnod *n; 552*7c478bd9Sstevel@tonic-gate { 553*7c478bd9Sstevel@tonic-gate register unsigned char *s; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate sigchk(); 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate if (n->namflg & N_FUNCTN) 558*7c478bd9Sstevel@tonic-gate { 559*7c478bd9Sstevel@tonic-gate prs_buff(n->namid); 560*7c478bd9Sstevel@tonic-gate prs_buff("(){\n"); 561*7c478bd9Sstevel@tonic-gate prf(n->namenv); 562*7c478bd9Sstevel@tonic-gate prs_buff("\n}\n"); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate else if (s = n->namval) 565*7c478bd9Sstevel@tonic-gate { 566*7c478bd9Sstevel@tonic-gate prs_buff(n->namid); 567*7c478bd9Sstevel@tonic-gate prc_buff('='); 568*7c478bd9Sstevel@tonic-gate prs_buff(s); 569*7c478bd9Sstevel@tonic-gate prc_buff(NL); 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate static unsigned char * 574*7c478bd9Sstevel@tonic-gate staknam(n) 575*7c478bd9Sstevel@tonic-gate register struct namnod *n; 576*7c478bd9Sstevel@tonic-gate { 577*7c478bd9Sstevel@tonic-gate register unsigned char *p; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate p = movstrstak(n->namid, staktop); 580*7c478bd9Sstevel@tonic-gate p = movstrstak("=", p); 581*7c478bd9Sstevel@tonic-gate p = movstrstak(n->namval, p); 582*7c478bd9Sstevel@tonic-gate return(getstak(p + 1 - (unsigned char *)(stakbot))); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate static int namec; 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate exname(n) 588*7c478bd9Sstevel@tonic-gate register struct namnod *n; 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate register int flg = n->namflg; 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (flg & N_ENVCHG) 593*7c478bd9Sstevel@tonic-gate { 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate if (flg & N_EXPORT) 596*7c478bd9Sstevel@tonic-gate { 597*7c478bd9Sstevel@tonic-gate free(n->namenv); 598*7c478bd9Sstevel@tonic-gate n->namenv = make(n->namval); 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate else 601*7c478bd9Sstevel@tonic-gate { 602*7c478bd9Sstevel@tonic-gate free(n->namval); 603*7c478bd9Sstevel@tonic-gate n->namval = make(n->namenv); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate if (!(flg & N_FUNCTN)) 609*7c478bd9Sstevel@tonic-gate n->namflg = N_DEFAULT; 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate if (n->namval) 612*7c478bd9Sstevel@tonic-gate namec++; 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate printro(n) 617*7c478bd9Sstevel@tonic-gate register struct namnod *n; 618*7c478bd9Sstevel@tonic-gate { 619*7c478bd9Sstevel@tonic-gate if (n->namflg & N_RDONLY) 620*7c478bd9Sstevel@tonic-gate { 621*7c478bd9Sstevel@tonic-gate prs_buff(readonly); 622*7c478bd9Sstevel@tonic-gate prc_buff(SPACE); 623*7c478bd9Sstevel@tonic-gate prs_buff(n->namid); 624*7c478bd9Sstevel@tonic-gate prc_buff(NL); 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate printexp(n) 629*7c478bd9Sstevel@tonic-gate register struct namnod *n; 630*7c478bd9Sstevel@tonic-gate { 631*7c478bd9Sstevel@tonic-gate if (n->namflg & N_EXPORT) 632*7c478bd9Sstevel@tonic-gate { 633*7c478bd9Sstevel@tonic-gate prs_buff(export); 634*7c478bd9Sstevel@tonic-gate prc_buff(SPACE); 635*7c478bd9Sstevel@tonic-gate prs_buff(n->namid); 636*7c478bd9Sstevel@tonic-gate prc_buff(NL); 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate setup_env() 641*7c478bd9Sstevel@tonic-gate { 642*7c478bd9Sstevel@tonic-gate register unsigned char **e = environ; 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate while (*e) 645*7c478bd9Sstevel@tonic-gate setname(*e++, N_ENVNAM); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate static unsigned char **argnam; 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate static 652*7c478bd9Sstevel@tonic-gate countnam(n) 653*7c478bd9Sstevel@tonic-gate struct namnod *n; 654*7c478bd9Sstevel@tonic-gate { 655*7c478bd9Sstevel@tonic-gate if (n->namval) 656*7c478bd9Sstevel@tonic-gate namec++; 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate static 660*7c478bd9Sstevel@tonic-gate pushnam(n) 661*7c478bd9Sstevel@tonic-gate register struct namnod *n; 662*7c478bd9Sstevel@tonic-gate { 663*7c478bd9Sstevel@tonic-gate register int flg = n->namflg; 664*7c478bd9Sstevel@tonic-gate register unsigned char *p; 665*7c478bd9Sstevel@tonic-gate register unsigned char *namval; 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate if (((flg & N_ENVCHG) && (flg & N_EXPORT)) || (flg & N_FUNCTN)) 668*7c478bd9Sstevel@tonic-gate namval = n->namval; 669*7c478bd9Sstevel@tonic-gate else { 670*7c478bd9Sstevel@tonic-gate /* Discard Local variable in child process */ 671*7c478bd9Sstevel@tonic-gate if (!(flg & ~N_ENVCHG)) { 672*7c478bd9Sstevel@tonic-gate n->namflg = 0; 673*7c478bd9Sstevel@tonic-gate n->namenv = 0; 674*7c478bd9Sstevel@tonic-gate if (n->namval) { 675*7c478bd9Sstevel@tonic-gate /* Release for re-use */ 676*7c478bd9Sstevel@tonic-gate free(n->namval); 677*7c478bd9Sstevel@tonic-gate n->namval = (unsigned char *)NIL; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate namval = n->namenv; 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate if (namval) 684*7c478bd9Sstevel@tonic-gate { 685*7c478bd9Sstevel@tonic-gate p = movstrstak(n->namid, staktop); 686*7c478bd9Sstevel@tonic-gate p = movstrstak("=", p); 687*7c478bd9Sstevel@tonic-gate p = movstrstak(namval, p); 688*7c478bd9Sstevel@tonic-gate *argnam++ = getstak(p + 1 - (unsigned char *)(stakbot)); 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate } 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate unsigned char ** 693*7c478bd9Sstevel@tonic-gate local_setenv() 694*7c478bd9Sstevel@tonic-gate { 695*7c478bd9Sstevel@tonic-gate register unsigned char **er; 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate namec = 0; 698*7c478bd9Sstevel@tonic-gate namscan(countnam); 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate argnam = er = (unsigned char **)getstak(namec * BYTESPERWORD + BYTESPERWORD); 701*7c478bd9Sstevel@tonic-gate namscan(pushnam); 702*7c478bd9Sstevel@tonic-gate *argnam++ = 0; 703*7c478bd9Sstevel@tonic-gate return(er); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate void 707*7c478bd9Sstevel@tonic-gate setvars() 708*7c478bd9Sstevel@tonic-gate { 709*7c478bd9Sstevel@tonic-gate namscan(exname); 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate struct namnod * 713*7c478bd9Sstevel@tonic-gate findnam(nam) 714*7c478bd9Sstevel@tonic-gate register unsigned char *nam; 715*7c478bd9Sstevel@tonic-gate { 716*7c478bd9Sstevel@tonic-gate register struct namnod *nscan = namep; 717*7c478bd9Sstevel@tonic-gate int LR; 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate if (!chkid(nam)) 720*7c478bd9Sstevel@tonic-gate return(0); 721*7c478bd9Sstevel@tonic-gate while (nscan) 722*7c478bd9Sstevel@tonic-gate { 723*7c478bd9Sstevel@tonic-gate if ((LR = cf(nam, nscan->namid)) == 0) 724*7c478bd9Sstevel@tonic-gate return(nscan); 725*7c478bd9Sstevel@tonic-gate else if (LR < 0) 726*7c478bd9Sstevel@tonic-gate nscan = nscan->namlft; 727*7c478bd9Sstevel@tonic-gate else 728*7c478bd9Sstevel@tonic-gate nscan = nscan->namrgt; 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate return(0); 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate unset_name(name) 735*7c478bd9Sstevel@tonic-gate register unsigned char *name; 736*7c478bd9Sstevel@tonic-gate { 737*7c478bd9Sstevel@tonic-gate register struct namnod *n; 738*7c478bd9Sstevel@tonic-gate register unsigned char call_dolocale = 0; 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate if (n = findnam(name)) 741*7c478bd9Sstevel@tonic-gate { 742*7c478bd9Sstevel@tonic-gate if (n->namflg & N_RDONLY) 743*7c478bd9Sstevel@tonic-gate failed(name, wtfailed); 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate if (n == &pathnod || 746*7c478bd9Sstevel@tonic-gate n == &ifsnod || 747*7c478bd9Sstevel@tonic-gate n == &ps1nod || 748*7c478bd9Sstevel@tonic-gate n == &ps2nod || 749*7c478bd9Sstevel@tonic-gate n == &mchknod) 750*7c478bd9Sstevel@tonic-gate { 751*7c478bd9Sstevel@tonic-gate failed(name, badunset); 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate #ifndef RES 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate if ((flags & rshflg) && eq(name, "SHELL")) 757*7c478bd9Sstevel@tonic-gate failed(name, restricted); 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate #endif 760*7c478bd9Sstevel@tonic-gate 761*7c478bd9Sstevel@tonic-gate if (n->namflg & N_FUNCTN) 762*7c478bd9Sstevel@tonic-gate { 763*7c478bd9Sstevel@tonic-gate func_unhash(name); 764*7c478bd9Sstevel@tonic-gate freefunc(n); 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate else 767*7c478bd9Sstevel@tonic-gate { 768*7c478bd9Sstevel@tonic-gate call_dolocale++; 769*7c478bd9Sstevel@tonic-gate free(n->namval); 770*7c478bd9Sstevel@tonic-gate free(n->namenv); 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate n->namval = n->namenv = 0; 774*7c478bd9Sstevel@tonic-gate n->namflg = N_DEFAULT; 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate if (call_dolocale) 777*7c478bd9Sstevel@tonic-gate dolocale(name); 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate if (flags & prompt) 780*7c478bd9Sstevel@tonic-gate { 781*7c478bd9Sstevel@tonic-gate if (n == &mailpnod) 782*7c478bd9Sstevel@tonic-gate setmail(mailnod.namval); 783*7c478bd9Sstevel@tonic-gate else if (n == &mailnod && mailpnod.namflg == N_DEFAULT) 784*7c478bd9Sstevel@tonic-gate setmail(0); 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate } 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate /* 790*7c478bd9Sstevel@tonic-gate * The environment variables which affect locale. 791*7c478bd9Sstevel@tonic-gate * Note: if all names in this list do not begin with 'L', 792*7c478bd9Sstevel@tonic-gate * you MUST modify dolocale(). Also, be sure that the 793*7c478bd9Sstevel@tonic-gate * fake_env has the same number of elements as localevar. 794*7c478bd9Sstevel@tonic-gate */ 795*7c478bd9Sstevel@tonic-gate static char *localevar[] = { 796*7c478bd9Sstevel@tonic-gate "LC_ALL", 797*7c478bd9Sstevel@tonic-gate "LC_CTYPE", 798*7c478bd9Sstevel@tonic-gate "LC_MESSAGES", 799*7c478bd9Sstevel@tonic-gate "LANG", 800*7c478bd9Sstevel@tonic-gate 0 801*7c478bd9Sstevel@tonic-gate }; 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate static char *fake_env[] = { 804*7c478bd9Sstevel@tonic-gate 0, 805*7c478bd9Sstevel@tonic-gate 0, 806*7c478bd9Sstevel@tonic-gate 0, 807*7c478bd9Sstevel@tonic-gate 0, 808*7c478bd9Sstevel@tonic-gate 0 809*7c478bd9Sstevel@tonic-gate }; 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate /* 812*7c478bd9Sstevel@tonic-gate * If name is one of several special variables which affect the locale, 813*7c478bd9Sstevel@tonic-gate * do a setlocale(). 814*7c478bd9Sstevel@tonic-gate */ 815*7c478bd9Sstevel@tonic-gate static void 816*7c478bd9Sstevel@tonic-gate dolocale(nm) 817*7c478bd9Sstevel@tonic-gate char *nm; 818*7c478bd9Sstevel@tonic-gate { 819*7c478bd9Sstevel@tonic-gate char **real_env; 820*7c478bd9Sstevel@tonic-gate struct namnod *n; 821*7c478bd9Sstevel@tonic-gate int lv, fe; 822*7c478bd9Sstevel@tonic-gate int i; 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate /* 825*7c478bd9Sstevel@tonic-gate * Take advantage of fact that names of these vars all start 826*7c478bd9Sstevel@tonic-gate * with 'L' to avoid unnecessary work. 827*7c478bd9Sstevel@tonic-gate * Do locale processing only if /usr is mounted. 828*7c478bd9Sstevel@tonic-gate */ 829*7c478bd9Sstevel@tonic-gate if ((*nm != 'L') || !localedir_exists || 830*7c478bd9Sstevel@tonic-gate (!(eq(nm, "LC_ALL") || eq(nm, "LC_CTYPE") || 831*7c478bd9Sstevel@tonic-gate eq(nm, "LANG") || eq(nm, "LC_MESSAGES")))) 832*7c478bd9Sstevel@tonic-gate return; 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate /* 835*7c478bd9Sstevel@tonic-gate * setlocale() has all the smarts built into it, but 836*7c478bd9Sstevel@tonic-gate * it works by examining the environment. Unfortunately, 837*7c478bd9Sstevel@tonic-gate * when you set an environment variable, the shell does 838*7c478bd9Sstevel@tonic-gate * not modify its own environment; it just remembers that the 839*7c478bd9Sstevel@tonic-gate * variable needs to be exported to any children. We hack around 840*7c478bd9Sstevel@tonic-gate * this by consing up a fake environment for the use of setlocale() 841*7c478bd9Sstevel@tonic-gate * and substituting it for the real env before calling setlocale(). 842*7c478bd9Sstevel@tonic-gate */ 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate /* 845*7c478bd9Sstevel@tonic-gate * Build the fake environment. 846*7c478bd9Sstevel@tonic-gate * Look up the value of each of the special environment 847*7c478bd9Sstevel@tonic-gate * variables, and put their value into the fake environment, 848*7c478bd9Sstevel@tonic-gate * if they are exported. 849*7c478bd9Sstevel@tonic-gate */ 850*7c478bd9Sstevel@tonic-gate for (lv = 0, fe = 0; localevar[lv]; lv++) { 851*7c478bd9Sstevel@tonic-gate if ((n = findnam(localevar[lv]))) { 852*7c478bd9Sstevel@tonic-gate register char *p, *q; 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate if (!n->namval) 855*7c478bd9Sstevel@tonic-gate continue; 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate fake_env[fe++] = p = alloc(length(localevar[lv]) 858*7c478bd9Sstevel@tonic-gate + length(n->namval) + 2); 859*7c478bd9Sstevel@tonic-gate /* copy name */ 860*7c478bd9Sstevel@tonic-gate q = localevar[lv]; 861*7c478bd9Sstevel@tonic-gate while (*q) 862*7c478bd9Sstevel@tonic-gate *p++ = *q++; 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate *p++ = '='; 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate /* copy value */ 867*7c478bd9Sstevel@tonic-gate q = (char*)(n->namval); 868*7c478bd9Sstevel@tonic-gate while (*q) 869*7c478bd9Sstevel@tonic-gate *p++ = *q++; 870*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate fake_env[fe] = (char *)0; 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate /* 876*7c478bd9Sstevel@tonic-gate * Switch fake env for real and call setlocale(). 877*7c478bd9Sstevel@tonic-gate */ 878*7c478bd9Sstevel@tonic-gate real_env = (char **)environ; 879*7c478bd9Sstevel@tonic-gate environ = (unsigned char **)fake_env; 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate if (setlocale(LC_ALL, "") == NULL) 882*7c478bd9Sstevel@tonic-gate prs("couldn't set locale correctly\n"); 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate /* 885*7c478bd9Sstevel@tonic-gate * Switch back and tear down the fake env. 886*7c478bd9Sstevel@tonic-gate */ 887*7c478bd9Sstevel@tonic-gate environ = (unsigned char **)real_env; 888*7c478bd9Sstevel@tonic-gate for (i = 0; i < fe; i++) { 889*7c478bd9Sstevel@tonic-gate free(fake_env[i]); 890*7c478bd9Sstevel@tonic-gate fake_env[i] = (char *)0; 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate } 893