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
options(int argc,unsigned char ** argv)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
setargs(unsigned char * argi[])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
freedolh(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 *
freeargs(blk)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 *
copyargs(from,n)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 *
clean_args(blk)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
clearup(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
savargs(funcnt)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
restorargs(olddolh,funcnt)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 *
useargs()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