xref: /freebsd/contrib/tcsh/sh.misc.c (revision 23338178da74e9862b8abd49eef83ee891027a1e)
123338178SMark Peek /* $Header: /src/pub/tcsh/sh.misc.c,v 3.34 2005/01/18 20:24:50 christos Exp $ */
2c80476e4SDavid E. O'Brien /*
3c80476e4SDavid E. O'Brien  * sh.misc.c: Miscelaneous functions
4c80476e4SDavid E. O'Brien  */
5c80476e4SDavid E. O'Brien /*-
6c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
7c80476e4SDavid E. O'Brien  * All rights reserved.
8c80476e4SDavid E. O'Brien  *
9c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
10c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
11c80476e4SDavid E. O'Brien  * are met:
12c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
13c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
14c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
15c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
16c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
1729301572SMark Peek  * 3. Neither the name of the University nor the names of its contributors
18c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
19c80476e4SDavid E. O'Brien  *    without specific prior written permission.
20c80476e4SDavid E. O'Brien  *
21c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
32c80476e4SDavid E. O'Brien  */
33c80476e4SDavid E. O'Brien #include "sh.h"
34c80476e4SDavid E. O'Brien 
3523338178SMark Peek RCSID("$Id: sh.misc.c,v 3.34 2005/01/18 20:24:50 christos Exp $")
36c80476e4SDavid E. O'Brien 
37c80476e4SDavid E. O'Brien static	int	renum	__P((int, int));
38c80476e4SDavid E. O'Brien static  Char  **blkend	__P((Char **));
39c80476e4SDavid E. O'Brien static  Char  **blkcat	__P((Char **, Char **));
40c80476e4SDavid E. O'Brien 
41c80476e4SDavid E. O'Brien /*
42c80476e4SDavid E. O'Brien  * C Shell
43c80476e4SDavid E. O'Brien  */
44c80476e4SDavid E. O'Brien 
45c80476e4SDavid E. O'Brien int
46c80476e4SDavid E. O'Brien any(s, c)
4723338178SMark Peek     const char *s;
4823338178SMark Peek     Char c;
49c80476e4SDavid E. O'Brien {
50c80476e4SDavid E. O'Brien     if (!s)
51c80476e4SDavid E. O'Brien 	return (0);		/* Check for nil pointer */
52c80476e4SDavid E. O'Brien     while (*s)
5323338178SMark Peek 	if ((Char)*s++ == c)
54c80476e4SDavid E. O'Brien 	    return (1);
55c80476e4SDavid E. O'Brien     return (0);
56c80476e4SDavid E. O'Brien }
57c80476e4SDavid E. O'Brien 
58c80476e4SDavid E. O'Brien void
59c80476e4SDavid E. O'Brien setzero(cp, i)
60c80476e4SDavid E. O'Brien     char   *cp;
61c80476e4SDavid E. O'Brien     int     i;
62c80476e4SDavid E. O'Brien {
63c80476e4SDavid E. O'Brien     if (i != 0)
64c80476e4SDavid E. O'Brien 	do
65c80476e4SDavid E. O'Brien 	    *cp++ = 0;
66c80476e4SDavid E. O'Brien 	while (--i);
67c80476e4SDavid E. O'Brien }
68c80476e4SDavid E. O'Brien 
69c80476e4SDavid E. O'Brien char   *
70c80476e4SDavid E. O'Brien strsave(s)
7123338178SMark Peek     const char *s;
72c80476e4SDavid E. O'Brien {
7323338178SMark Peek     char   *n, *r;
7423338178SMark Peek     const char *p;
75c80476e4SDavid E. O'Brien 
76c80476e4SDavid E. O'Brien     if (s == NULL)
7723338178SMark Peek 	s = "";
7823338178SMark Peek     for (p = s; *p++ != '\0';)
79c80476e4SDavid E. O'Brien 	continue;
8023338178SMark Peek     r = n = (char *) xmalloc((size_t)((((const char *) p) - s) * sizeof(char)));
8123338178SMark Peek     while ((*n++ = *s++) != '\0')
82c80476e4SDavid E. O'Brien 	continue;
8323338178SMark Peek     return (r);
84c80476e4SDavid E. O'Brien }
85c80476e4SDavid E. O'Brien 
86c80476e4SDavid E. O'Brien static Char  **
87c80476e4SDavid E. O'Brien blkend(up)
8823338178SMark Peek     Char **up;
89c80476e4SDavid E. O'Brien {
90c80476e4SDavid E. O'Brien 
91c80476e4SDavid E. O'Brien     while (*up)
92c80476e4SDavid E. O'Brien 	up++;
93c80476e4SDavid E. O'Brien     return (up);
94c80476e4SDavid E. O'Brien }
95c80476e4SDavid E. O'Brien 
96c80476e4SDavid E. O'Brien 
97c80476e4SDavid E. O'Brien void
98c80476e4SDavid E. O'Brien blkpr(av)
9923338178SMark Peek     Char **av;
100c80476e4SDavid E. O'Brien {
101c80476e4SDavid E. O'Brien 
102c80476e4SDavid E. O'Brien     for (; *av; av++) {
103c80476e4SDavid E. O'Brien 	xprintf("%S", *av);
104c80476e4SDavid E. O'Brien 	if (av[1])
105c80476e4SDavid E. O'Brien 	    xprintf(" ");
106c80476e4SDavid E. O'Brien     }
107c80476e4SDavid E. O'Brien }
108c80476e4SDavid E. O'Brien 
109c80476e4SDavid E. O'Brien void
110c80476e4SDavid E. O'Brien blkexpand(av, str)
11123338178SMark Peek     Char **av;
112c80476e4SDavid E. O'Brien     Char *str;
113c80476e4SDavid E. O'Brien {
114c80476e4SDavid E. O'Brien     *str = '\0';
115c80476e4SDavid E. O'Brien     for (; *av; av++) {
116c80476e4SDavid E. O'Brien 	(void) Strcat(str, *av);
117c80476e4SDavid E. O'Brien 	if (av[1])
118c80476e4SDavid E. O'Brien 	    (void) Strcat(str, STRspace);
119c80476e4SDavid E. O'Brien     }
120c80476e4SDavid E. O'Brien }
121c80476e4SDavid E. O'Brien 
122c80476e4SDavid E. O'Brien int
123c80476e4SDavid E. O'Brien blklen(av)
12423338178SMark Peek     Char **av;
125c80476e4SDavid E. O'Brien {
12623338178SMark Peek     int i = 0;
127c80476e4SDavid E. O'Brien 
128c80476e4SDavid E. O'Brien     while (*av++)
129c80476e4SDavid E. O'Brien 	i++;
130c80476e4SDavid E. O'Brien     return (i);
131c80476e4SDavid E. O'Brien }
132c80476e4SDavid E. O'Brien 
133c80476e4SDavid E. O'Brien Char  **
134c80476e4SDavid E. O'Brien blkcpy(oav, bv)
135c80476e4SDavid E. O'Brien     Char  **oav;
13623338178SMark Peek     Char **bv;
137c80476e4SDavid E. O'Brien {
13823338178SMark Peek     Char **av = oav;
139c80476e4SDavid E. O'Brien 
140c80476e4SDavid E. O'Brien     while ((*av++ = *bv++) != NULL)
141c80476e4SDavid E. O'Brien 	continue;
142c80476e4SDavid E. O'Brien     return (oav);
143c80476e4SDavid E. O'Brien }
144c80476e4SDavid E. O'Brien 
145c80476e4SDavid E. O'Brien static Char  **
146c80476e4SDavid E. O'Brien blkcat(up, vp)
147c80476e4SDavid E. O'Brien     Char  **up, **vp;
148c80476e4SDavid E. O'Brien {
149c80476e4SDavid E. O'Brien 
150c80476e4SDavid E. O'Brien     (void) blkcpy(blkend(up), vp);
151c80476e4SDavid E. O'Brien     return (up);
152c80476e4SDavid E. O'Brien }
153c80476e4SDavid E. O'Brien 
154c80476e4SDavid E. O'Brien void
155c80476e4SDavid E. O'Brien blkfree(av0)
156c80476e4SDavid E. O'Brien     Char  **av0;
157c80476e4SDavid E. O'Brien {
15823338178SMark Peek     Char **av = av0;
159c80476e4SDavid E. O'Brien 
160c80476e4SDavid E. O'Brien     if (!av0)
161c80476e4SDavid E. O'Brien 	return;
162c80476e4SDavid E. O'Brien     for (; *av; av++)
163c80476e4SDavid E. O'Brien 	xfree((ptr_t) * av);
164c80476e4SDavid E. O'Brien     xfree((ptr_t) av0);
165c80476e4SDavid E. O'Brien }
166c80476e4SDavid E. O'Brien 
167c80476e4SDavid E. O'Brien Char  **
168c80476e4SDavid E. O'Brien saveblk(v)
16923338178SMark Peek     Char **v;
170c80476e4SDavid E. O'Brien {
17123338178SMark Peek     Char **newv =
172c80476e4SDavid E. O'Brien     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
173c80476e4SDavid E. O'Brien     Char  **onewv = newv;
174c80476e4SDavid E. O'Brien 
175c80476e4SDavid E. O'Brien     while (*v)
176c80476e4SDavid E. O'Brien 	*newv++ = Strsave(*v++);
177c80476e4SDavid E. O'Brien     return (onewv);
178c80476e4SDavid E. O'Brien }
179c80476e4SDavid E. O'Brien 
18023338178SMark Peek #ifndef HAVE_STRSTR
181c80476e4SDavid E. O'Brien char   *
182c80476e4SDavid E. O'Brien strstr(s, t)
18323338178SMark Peek     const char *s, *t;
184c80476e4SDavid E. O'Brien {
185c80476e4SDavid E. O'Brien     do {
18623338178SMark Peek 	const char *ss = s;
18723338178SMark Peek 	const char *tt = t;
188c80476e4SDavid E. O'Brien 
189c80476e4SDavid E. O'Brien 	do
190c80476e4SDavid E. O'Brien 	    if (*tt == '\0')
191c80476e4SDavid E. O'Brien 		return ((char *) s);
192c80476e4SDavid E. O'Brien 	while (*ss++ == *tt++);
193c80476e4SDavid E. O'Brien     } while (*s++ != '\0');
194c80476e4SDavid E. O'Brien     return (NULL);
195c80476e4SDavid E. O'Brien }
19623338178SMark Peek #endif /* !HAVE_STRSTR */
197c80476e4SDavid E. O'Brien 
198c80476e4SDavid E. O'Brien #ifndef SHORT_STRINGS
199c80476e4SDavid E. O'Brien char   *
200c80476e4SDavid E. O'Brien strspl(cp, dp)
20123338178SMark Peek     const char *cp, *dp;
202c80476e4SDavid E. O'Brien {
203c80476e4SDavid E. O'Brien     char   *ep;
20423338178SMark Peek     size_t cl, dl;
205c80476e4SDavid E. O'Brien 
206c80476e4SDavid E. O'Brien     if (!cp)
207c80476e4SDavid E. O'Brien 	cp = "";
208c80476e4SDavid E. O'Brien     if (!dp)
209c80476e4SDavid E. O'Brien 	dp = "";
21023338178SMark Peek     cl = strlen(cp);
21123338178SMark Peek     dl = strlen(dp);
21223338178SMark Peek     ep = (char *) xmalloc((cl + dl + 1) * sizeof(char));
21323338178SMark Peek     memcpy(ep, cp, cl);
21423338178SMark Peek     memcpy(ep + cl, dp, dl + 1);
215c80476e4SDavid E. O'Brien     return (ep);
216c80476e4SDavid E. O'Brien }
217c80476e4SDavid E. O'Brien 
218c80476e4SDavid E. O'Brien #endif /* !SHORT_STRINGS */
219c80476e4SDavid E. O'Brien 
220c80476e4SDavid E. O'Brien Char  **
221c80476e4SDavid E. O'Brien blkspl(up, vp)
22223338178SMark Peek     Char **up, **vp;
223c80476e4SDavid E. O'Brien {
22423338178SMark Peek     Char **wp =
225c80476e4SDavid E. O'Brien     (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
226c80476e4SDavid E. O'Brien 		      sizeof(Char **));
227c80476e4SDavid E. O'Brien 
228c80476e4SDavid E. O'Brien     (void) blkcpy(wp, up);
229c80476e4SDavid E. O'Brien     return (blkcat(wp, vp));
230c80476e4SDavid E. O'Brien }
231c80476e4SDavid E. O'Brien 
232c80476e4SDavid E. O'Brien Char
233c80476e4SDavid E. O'Brien lastchr(cp)
23423338178SMark Peek     Char *cp;
235c80476e4SDavid E. O'Brien {
236c80476e4SDavid E. O'Brien 
237c80476e4SDavid E. O'Brien     if (!cp)
238c80476e4SDavid E. O'Brien 	return (0);
239c80476e4SDavid E. O'Brien     if (!*cp)
240c80476e4SDavid E. O'Brien 	return (0);
241c80476e4SDavid E. O'Brien     while (cp[1])
242c80476e4SDavid E. O'Brien 	cp++;
243c80476e4SDavid E. O'Brien     return (*cp);
244c80476e4SDavid E. O'Brien }
245c80476e4SDavid E. O'Brien 
246c80476e4SDavid E. O'Brien /*
247c80476e4SDavid E. O'Brien  * This routine is called after an error to close up
248c80476e4SDavid E. O'Brien  * any units which may have been left open accidentally.
249c80476e4SDavid E. O'Brien  */
250c80476e4SDavid E. O'Brien void
251c80476e4SDavid E. O'Brien closem()
252c80476e4SDavid E. O'Brien {
25323338178SMark Peek     int f;
254c80476e4SDavid E. O'Brien 
255b2d5d167SMark Peek #ifdef NLS_BUGS
256b2d5d167SMark Peek #ifdef NLS_CATALOGS
25723338178SMark Peek     nlsclose();
258b2d5d167SMark Peek #endif /* NLS_CATALOGS */
259b2d5d167SMark Peek #endif /* NLS_BUGS */
260c80476e4SDavid E. O'Brien #ifdef YPBUGS
261c80476e4SDavid E. O'Brien     /* suggested by Justin Bur; thanks to Karl Kleinpaste */
262c80476e4SDavid E. O'Brien     fix_yp_bugs();
263c80476e4SDavid E. O'Brien #endif /* YPBUGS */
264c80476e4SDavid E. O'Brien     for (f = 0; f < NOFILE; f++)
265c80476e4SDavid E. O'Brien 	if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
266c80476e4SDavid E. O'Brien 	    f != FSHTTY
267c80476e4SDavid E. O'Brien #ifdef MALLOC_TRACE
268c80476e4SDavid E. O'Brien 	    && f != 25
269c80476e4SDavid E. O'Brien #endif /* MALLOC_TRACE */
270c80476e4SDavid E. O'Brien 	    )
271c80476e4SDavid E. O'Brien 	  {
272c80476e4SDavid E. O'Brien 	    (void) close(f);
273c80476e4SDavid E. O'Brien #ifdef NISPLUS
274c80476e4SDavid E. O'Brien 	    if(f < 3)
275b2d5d167SMark Peek 		(void) open(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
276c80476e4SDavid E. O'Brien #endif /* NISPLUS */
277c80476e4SDavid E. O'Brien 	  }
278b2d5d167SMark Peek #ifdef NLS_BUGS
279b2d5d167SMark Peek #ifdef NLS_CATALOGS
280b2d5d167SMark Peek     nlsinit();
281b2d5d167SMark Peek #endif /* NLS_CATALOGS */
282b2d5d167SMark Peek #endif /* NLS_BUGS */
283c80476e4SDavid E. O'Brien }
284c80476e4SDavid E. O'Brien 
285c80476e4SDavid E. O'Brien #ifndef CLOSE_ON_EXEC
286c80476e4SDavid E. O'Brien /*
287c80476e4SDavid E. O'Brien  * Close files before executing a file.
288c80476e4SDavid E. O'Brien  * We could be MUCH more intelligent, since (on a version 7 system)
289c80476e4SDavid E. O'Brien  * we need only close files here during a source, the other
290c80476e4SDavid E. O'Brien  * shell fd's being in units 16-19 which are closed automatically!
291c80476e4SDavid E. O'Brien  */
292c80476e4SDavid E. O'Brien void
293c80476e4SDavid E. O'Brien closech()
294c80476e4SDavid E. O'Brien {
29523338178SMark Peek     int f;
296c80476e4SDavid E. O'Brien 
297c80476e4SDavid E. O'Brien     if (didcch)
298c80476e4SDavid E. O'Brien 	return;
299c80476e4SDavid E. O'Brien     didcch = 1;
300c80476e4SDavid E. O'Brien     SHIN = 0;
301c80476e4SDavid E. O'Brien     SHOUT = 1;
302c80476e4SDavid E. O'Brien     SHDIAG = 2;
303c80476e4SDavid E. O'Brien     OLDSTD = 0;
304c80476e4SDavid E. O'Brien     isoutatty = isatty(SHOUT);
305c80476e4SDavid E. O'Brien     isdiagatty = isatty(SHDIAG);
306c80476e4SDavid E. O'Brien     for (f = 3; f < NOFILE; f++)
307c80476e4SDavid E. O'Brien 	(void) close(f);
308c80476e4SDavid E. O'Brien }
309c80476e4SDavid E. O'Brien 
310c80476e4SDavid E. O'Brien #endif /* CLOSE_ON_EXEC */
311c80476e4SDavid E. O'Brien 
312c80476e4SDavid E. O'Brien void
313c80476e4SDavid E. O'Brien donefds()
314c80476e4SDavid E. O'Brien {
315c80476e4SDavid E. O'Brien 
316c80476e4SDavid E. O'Brien     (void) close(0);
317c80476e4SDavid E. O'Brien     (void) close(1);
318c80476e4SDavid E. O'Brien     (void) close(2);
319c80476e4SDavid E. O'Brien     didfds = 0;
320c80476e4SDavid E. O'Brien #ifdef NISPLUS
321c80476e4SDavid E. O'Brien     {
322b2d5d167SMark Peek 	int fd = open(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
32323338178SMark Peek 	(void)dcopy(fd, 1);
32423338178SMark Peek 	(void)dcopy(fd, 2);
32523338178SMark Peek 	(void)dmove(fd, 0);
326c80476e4SDavid E. O'Brien     }
327c80476e4SDavid E. O'Brien #endif /*NISPLUS*/
328c80476e4SDavid E. O'Brien }
329c80476e4SDavid E. O'Brien 
330c80476e4SDavid E. O'Brien /*
331c80476e4SDavid E. O'Brien  * Move descriptor i to j.
332c80476e4SDavid E. O'Brien  * If j is -1 then we just want to get i to a safe place,
33323338178SMark Peek  * i.e. to a unit > FSAFE.  This also happens in dcopy.
334c80476e4SDavid E. O'Brien  */
335c80476e4SDavid E. O'Brien int
336c80476e4SDavid E. O'Brien dmove(i, j)
33723338178SMark Peek     int i, j;
338c80476e4SDavid E. O'Brien {
339c80476e4SDavid E. O'Brien 
340c80476e4SDavid E. O'Brien     if (i == j || i < 0)
341c80476e4SDavid E. O'Brien 	return (i);
34223338178SMark Peek #ifdef HAVE_DUP2
343c80476e4SDavid E. O'Brien     if (j >= 0) {
344c80476e4SDavid E. O'Brien 	(void) dup2(i, j);
345c80476e4SDavid E. O'Brien 	if (j != i)
346c80476e4SDavid E. O'Brien 	    (void) close(i);
347c80476e4SDavid E. O'Brien 	return (j);
348c80476e4SDavid E. O'Brien     }
349c80476e4SDavid E. O'Brien #endif
350c80476e4SDavid E. O'Brien     j = dcopy(i, j);
351c80476e4SDavid E. O'Brien     if (j != i)
352c80476e4SDavid E. O'Brien 	(void) close(i);
353c80476e4SDavid E. O'Brien     return (j);
354c80476e4SDavid E. O'Brien }
355c80476e4SDavid E. O'Brien 
356c80476e4SDavid E. O'Brien int
357c80476e4SDavid E. O'Brien dcopy(i, j)
35823338178SMark Peek     int i, j;
359c80476e4SDavid E. O'Brien {
360c80476e4SDavid E. O'Brien 
36123338178SMark Peek     if (i == j || i < 0 || (j < 0 && i > FSAFE))
362c80476e4SDavid E. O'Brien 	return (i);
363c80476e4SDavid E. O'Brien     if (j >= 0) {
36423338178SMark Peek #ifdef HAVE_DUP2
365c80476e4SDavid E. O'Brien 	(void) dup2(i, j);
366c80476e4SDavid E. O'Brien 	return (j);
367c80476e4SDavid E. O'Brien #else
368c80476e4SDavid E. O'Brien 	(void) close(j);
369c80476e4SDavid E. O'Brien #endif
370c80476e4SDavid E. O'Brien     }
371c80476e4SDavid E. O'Brien     return (renum(i, j));
372c80476e4SDavid E. O'Brien }
373c80476e4SDavid E. O'Brien 
374c80476e4SDavid E. O'Brien static int
375c80476e4SDavid E. O'Brien renum(i, j)
37623338178SMark Peek     int i, j;
377c80476e4SDavid E. O'Brien {
37823338178SMark Peek     int k = dup(i);
379c80476e4SDavid E. O'Brien 
380c80476e4SDavid E. O'Brien     if (k < 0)
381c80476e4SDavid E. O'Brien 	return (-1);
38223338178SMark Peek     if (j == -1 && k > FSAFE)
383c80476e4SDavid E. O'Brien 	return (k);
384c80476e4SDavid E. O'Brien     if (k != j) {
385c80476e4SDavid E. O'Brien 	j = renum(k, j);
386c80476e4SDavid E. O'Brien 	(void) close(k);
387c80476e4SDavid E. O'Brien 	return (j);
388c80476e4SDavid E. O'Brien     }
389c80476e4SDavid E. O'Brien     return (k);
390c80476e4SDavid E. O'Brien }
391c80476e4SDavid E. O'Brien 
392c80476e4SDavid E. O'Brien /*
393c80476e4SDavid E. O'Brien  * Left shift a command argument list, discarding
394c80476e4SDavid E. O'Brien  * the first c arguments.  Used in "shift" commands
395c80476e4SDavid E. O'Brien  * as well as by commands like "repeat".
396c80476e4SDavid E. O'Brien  */
397c80476e4SDavid E. O'Brien void
398c80476e4SDavid E. O'Brien lshift(v, c)
39923338178SMark Peek     Char **v;
40023338178SMark Peek     int c;
401c80476e4SDavid E. O'Brien {
40223338178SMark Peek     Char **u;
403c80476e4SDavid E. O'Brien 
404c80476e4SDavid E. O'Brien     for (u = v; *u && --c >= 0; u++)
405c80476e4SDavid E. O'Brien 	xfree((ptr_t) *u);
406c80476e4SDavid E. O'Brien     (void) blkcpy(v, u);
407c80476e4SDavid E. O'Brien }
408c80476e4SDavid E. O'Brien 
409c80476e4SDavid E. O'Brien int
410c80476e4SDavid E. O'Brien number(cp)
411c80476e4SDavid E. O'Brien     Char   *cp;
412c80476e4SDavid E. O'Brien {
413c80476e4SDavid E. O'Brien     if (!cp)
414c80476e4SDavid E. O'Brien 	return (0);
415c80476e4SDavid E. O'Brien     if (*cp == '-') {
416c80476e4SDavid E. O'Brien 	cp++;
417c80476e4SDavid E. O'Brien 	if (!Isdigit(*cp))
418c80476e4SDavid E. O'Brien 	    return (0);
419c80476e4SDavid E. O'Brien 	cp++;
420c80476e4SDavid E. O'Brien     }
421c80476e4SDavid E. O'Brien     while (*cp && Isdigit(*cp))
422c80476e4SDavid E. O'Brien 	cp++;
423c80476e4SDavid E. O'Brien     return (*cp == 0);
424c80476e4SDavid E. O'Brien }
425c80476e4SDavid E. O'Brien 
426c80476e4SDavid E. O'Brien Char  **
427c80476e4SDavid E. O'Brien copyblk(v)
42823338178SMark Peek     Char **v;
429c80476e4SDavid E. O'Brien {
43023338178SMark Peek     Char **nv =
431c80476e4SDavid E. O'Brien     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
432c80476e4SDavid E. O'Brien 
433c80476e4SDavid E. O'Brien     return (blkcpy(nv, v));
434c80476e4SDavid E. O'Brien }
435c80476e4SDavid E. O'Brien 
436c80476e4SDavid E. O'Brien #ifndef SHORT_STRINGS
437c80476e4SDavid E. O'Brien char   *
438c80476e4SDavid E. O'Brien strend(cp)
43923338178SMark Peek     char *cp;
440c80476e4SDavid E. O'Brien {
441c80476e4SDavid E. O'Brien     if (!cp)
442c80476e4SDavid E. O'Brien 	return (cp);
443c80476e4SDavid E. O'Brien     while (*cp)
444c80476e4SDavid E. O'Brien 	cp++;
445c80476e4SDavid E. O'Brien     return (cp);
446c80476e4SDavid E. O'Brien }
447c80476e4SDavid E. O'Brien 
448c80476e4SDavid E. O'Brien #endif /* SHORT_STRINGS */
449c80476e4SDavid E. O'Brien 
450c80476e4SDavid E. O'Brien Char   *
451c80476e4SDavid E. O'Brien strip(cp)
452c80476e4SDavid E. O'Brien     Char   *cp;
453c80476e4SDavid E. O'Brien {
45423338178SMark Peek     Char *dp = cp;
455c80476e4SDavid E. O'Brien 
456c80476e4SDavid E. O'Brien     if (!cp)
457c80476e4SDavid E. O'Brien 	return (cp);
458c80476e4SDavid E. O'Brien     while ((*dp++ &= TRIM) != '\0')
459c80476e4SDavid E. O'Brien 	continue;
460c80476e4SDavid E. O'Brien     return (cp);
461c80476e4SDavid E. O'Brien }
462c80476e4SDavid E. O'Brien 
463c80476e4SDavid E. O'Brien Char   *
464c80476e4SDavid E. O'Brien quote(cp)
465c80476e4SDavid E. O'Brien     Char   *cp;
466c80476e4SDavid E. O'Brien {
46723338178SMark Peek     Char *dp = cp;
468c80476e4SDavid E. O'Brien 
469c80476e4SDavid E. O'Brien     if (!cp)
470c80476e4SDavid E. O'Brien 	return (cp);
471c80476e4SDavid E. O'Brien     while (*dp != '\0')
472c80476e4SDavid E. O'Brien 	*dp++ |= QUOTE;
473c80476e4SDavid E. O'Brien     return (cp);
474c80476e4SDavid E. O'Brien }
475c80476e4SDavid E. O'Brien 
476c80476e4SDavid E. O'Brien Char   *
477c80476e4SDavid E. O'Brien quote_meta(d, s)
478c80476e4SDavid E. O'Brien     Char   *d;
479c80476e4SDavid E. O'Brien     const Char   *s;
480c80476e4SDavid E. O'Brien {
481c80476e4SDavid E. O'Brien     Char *r = d;
482c80476e4SDavid E. O'Brien     while (*s != '\0') {
483c80476e4SDavid E. O'Brien 	if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB))
484c80476e4SDavid E. O'Brien 		*d++ = '\\';
485c80476e4SDavid E. O'Brien 	*d++ = *s++;
486c80476e4SDavid E. O'Brien     }
487c80476e4SDavid E. O'Brien     *d = '\0';
488c80476e4SDavid E. O'Brien     return r;
489c80476e4SDavid E. O'Brien }
490c80476e4SDavid E. O'Brien 
491c80476e4SDavid E. O'Brien void
492c80476e4SDavid E. O'Brien udvar(name)
493c80476e4SDavid E. O'Brien     Char   *name;
494c80476e4SDavid E. O'Brien {
495c80476e4SDavid E. O'Brien 
496c80476e4SDavid E. O'Brien     setname(short2str(name));
497c80476e4SDavid E. O'Brien     stderror(ERR_NAME | ERR_UNDVAR);
498c80476e4SDavid E. O'Brien }
499c80476e4SDavid E. O'Brien 
500c80476e4SDavid E. O'Brien int
501c80476e4SDavid E. O'Brien prefix(sub, str)
50223338178SMark Peek     const Char *sub, *str;
503c80476e4SDavid E. O'Brien {
504c80476e4SDavid E. O'Brien 
505c80476e4SDavid E. O'Brien     for (;;) {
506c80476e4SDavid E. O'Brien 	if (*sub == 0)
507c80476e4SDavid E. O'Brien 	    return (1);
508c80476e4SDavid E. O'Brien 	if (*str == 0)
509c80476e4SDavid E. O'Brien 	    return (0);
510c80476e4SDavid E. O'Brien 	if ((*sub++ & TRIM) != (*str++ & TRIM))
511c80476e4SDavid E. O'Brien 	    return (0);
512c80476e4SDavid E. O'Brien     }
513c80476e4SDavid E. O'Brien }
514