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