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
options(int argc,unsigned char ** argv)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
setargs(unsigned char * argi[])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
freedolh(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 *
freeargs(blk)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 *
copyargs(unsigned char * from[],int n)279 copyargs(unsigned char *from[], int n)
280 {
281 struct dolnod *np = (struct dolnod *)alloc(sizeof (struct dolnod));
282 unsigned char **fp = from;
283 unsigned char **pp;
284
285 np -> dolnxt = 0;
286 np->doluse = 1; /* use count */
287 pp = np->dolarg = (unsigned char **)alloc((n+1)*sizeof(char *));
288 dolv = pp;
289
290 while (n--)
291 *pp++ = make(*fp++);
292 *pp++ = ENDARGS;
293 return(np);
294 }
295
296
297 struct dolnod *
clean_args(struct dolnod * blk)298 clean_args(struct dolnod *blk)
299 {
300 unsigned char **argp;
301 struct dolnod *argr = 0;
302 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 void
clearup(void)322 clearup(void)
323 {
324 /*
325 * force `for' $* lists to go away
326 */
327 if(globdolv)
328 dolv = globdolv;
329 if(globdolc)
330 dolc = globdolc;
331 if(globdolh)
332 dolh = globdolh;
333 globdolv = 0;
334 globdolc = 0;
335 globdolh = 0;
336 while (argfor = clean_args(argfor))
337 ;
338 /*
339 * clean up io files
340 */
341 while (pop())
342 ;
343
344 /*
345 * Clean up pipe file descriptor
346 * from command substitution
347 */
348
349 if(savpipe != -1) {
350 close(savpipe);
351 savpipe = -1;
352 }
353
354 /*
355 * clean up tmp files
356 */
357 while (poptemp())
358 ;
359 }
360
361 /*
362 * Save positiional parameters before outermost function invocation
363 * in case we are interrupted.
364 * Increment use count for current positional parameters so that they aren't thrown
365 * away.
366 */
367
savargs(funcnt)368 struct dolnod *savargs(funcnt)
369 int funcnt;
370 {
371 if (!funcnt) {
372 globdolh = dolh;
373 globdolv = dolv;
374 globdolc = dolc;
375 }
376 useargs();
377 return(dolh);
378 }
379
380 /* After function invocation, free positional parameters,
381 * restore old positional parameters, and restore
382 * use count.
383 */
384
restorargs(struct dolnod * olddolh,int funcnt)385 void restorargs(struct dolnod *olddolh, int funcnt)
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 *
useargs(void)404 useargs(void)
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