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