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