xref: /titanic_51/usr/src/cmd/sh/args.c (revision 92e807e650499591f2549dc94c6d20b81e94e394)
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