xref: /openbsd-src/bin/csh/misc.c (revision d95322bb7eaf29cae35b5ec04119262aa2cb0e45)
1*d95322bbSmartijn /*	$OpenBSD: misc.c,v 1.25 2018/10/24 06:01:03 martijn Exp $	*/
2df930be7Sderaadt /*	$NetBSD: misc.c,v 1.6 1995/03/21 09:03:09 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*-
5df930be7Sderaadt  * Copyright (c) 1980, 1991, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
1629295d1cSmillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
33f4faee91Sderaadt #include <sys/types.h>
34df930be7Sderaadt #include <stdlib.h>
35df930be7Sderaadt #include <unistd.h>
36df930be7Sderaadt #include <stdarg.h>
37df930be7Sderaadt 
38df930be7Sderaadt #include "csh.h"
39df930be7Sderaadt #include "extern.h"
40df930be7Sderaadt 
410b2eaac3Santon static int	fdcmp(int);
42c72b5b24Smillert static int	renum(int, int);
43df930be7Sderaadt 
445f867525Sderaadt int
any(char * s,int c)455f867525Sderaadt any(char *s, int c)
465f867525Sderaadt {
475f867525Sderaadt     if (!s)
485f867525Sderaadt 	return (0);		/* Check for nil pointer */
495f867525Sderaadt     while (*s)
505f867525Sderaadt 	if (*s++ == c)
515f867525Sderaadt 	    return (1);
525f867525Sderaadt     return (0);
535f867525Sderaadt }
545f867525Sderaadt 
55df930be7Sderaadt Char  **
blkend(Char ** up)56e757c91eSderaadt blkend(Char **up)
57df930be7Sderaadt {
58df930be7Sderaadt 
59df930be7Sderaadt     while (*up)
60df930be7Sderaadt 	up++;
61df930be7Sderaadt     return (up);
62df930be7Sderaadt }
63df930be7Sderaadt 
64df930be7Sderaadt 
65df930be7Sderaadt void
blkpr(FILE * fp,Char ** av)66e757c91eSderaadt blkpr(FILE *fp, Char **av)
67df930be7Sderaadt {
68df930be7Sderaadt 
69df930be7Sderaadt     for (; *av; av++) {
70df930be7Sderaadt 	(void) fprintf(fp, "%s", vis_str(*av));
71df930be7Sderaadt 	if (av[1])
72df930be7Sderaadt 	    (void) fprintf(fp, " ");
73df930be7Sderaadt     }
74df930be7Sderaadt }
75df930be7Sderaadt 
76df930be7Sderaadt int
blklen(Char ** av)77e757c91eSderaadt blklen(Char **av)
78df930be7Sderaadt {
79e757c91eSderaadt     int i = 0;
80df930be7Sderaadt 
81df930be7Sderaadt     while (*av++)
82df930be7Sderaadt 	i++;
83df930be7Sderaadt     return (i);
84df930be7Sderaadt }
85df930be7Sderaadt 
86df930be7Sderaadt Char  **
blkcpy(Char ** oav,Char ** bv)87e757c91eSderaadt blkcpy(Char **oav, Char **bv)
88df930be7Sderaadt {
89e757c91eSderaadt     Char **av = oav;
90df930be7Sderaadt 
91df930be7Sderaadt     while ((*av++ = *bv++) != NULL)
92df930be7Sderaadt 	continue;
93df930be7Sderaadt     return (oav);
94df930be7Sderaadt }
95df930be7Sderaadt 
96df930be7Sderaadt Char  **
blkcat(Char ** up,Char ** vp)97e757c91eSderaadt blkcat(Char **up, Char **vp)
98df930be7Sderaadt {
99df930be7Sderaadt 
100df930be7Sderaadt     (void) blkcpy(blkend(up), vp);
101df930be7Sderaadt     return (up);
102df930be7Sderaadt }
103df930be7Sderaadt 
104df930be7Sderaadt void
blkfree(Char ** av0)105e757c91eSderaadt blkfree(Char **av0)
106df930be7Sderaadt {
107e757c91eSderaadt     Char **av = av0;
108df930be7Sderaadt 
109df930be7Sderaadt     if (!av0)
110df930be7Sderaadt 	return;
111df930be7Sderaadt     for (; *av; av++)
112acdb3202Smestre 	free(* av);
113acdb3202Smestre     free(av0);
114df930be7Sderaadt }
115df930be7Sderaadt 
116df930be7Sderaadt Char  **
saveblk(Char ** v)117e757c91eSderaadt saveblk(Char **v)
118df930be7Sderaadt {
119*d95322bbSmartijn     Char **newv = xcalloc(blklen(v) + 1, sizeof(*newv));
120df930be7Sderaadt     Char  **onewv = newv;
121df930be7Sderaadt 
122df930be7Sderaadt     while (*v)
123df930be7Sderaadt 	*newv++ = Strsave(*v++);
124df930be7Sderaadt     return (onewv);
125df930be7Sderaadt }
126df930be7Sderaadt 
127df930be7Sderaadt Char  **
blkspl(Char ** up,Char ** vp)128e757c91eSderaadt blkspl(Char **up, Char **vp)
129df930be7Sderaadt {
130*d95322bbSmartijn     Char **wp = xcalloc(blklen(up) + blklen(vp) + 1, sizeof(*wp));
131df930be7Sderaadt 
132df930be7Sderaadt     (void) blkcpy(wp, up);
133df930be7Sderaadt     return (blkcat(wp, vp));
134df930be7Sderaadt }
135df930be7Sderaadt 
136df930be7Sderaadt Char
lastchr(Char * cp)137e757c91eSderaadt lastchr(Char *cp)
138df930be7Sderaadt {
139df930be7Sderaadt 
140df930be7Sderaadt     if (!cp)
141df930be7Sderaadt 	return (0);
142df930be7Sderaadt     if (!*cp)
143df930be7Sderaadt 	return (0);
144df930be7Sderaadt     while (cp[1])
145df930be7Sderaadt 	cp++;
146df930be7Sderaadt     return (*cp);
147df930be7Sderaadt }
148df930be7Sderaadt 
149df930be7Sderaadt /*
1500b2eaac3Santon  * Returns 0 if fd is in use, 1 if fd is greater than the largest used file
1510b2eaac3Santon  * descriptor and -1 otherwise.
1520b2eaac3Santon  */
1530b2eaac3Santon static int
fdcmp(int fd)1540b2eaac3Santon fdcmp(int fd)
1550b2eaac3Santon {
1560b2eaac3Santon     int fds[] = { SHIN, SHOUT, SHERR, OLDSTD, FSHTTY };
1570b2eaac3Santon     int i, max;
1580b2eaac3Santon 
1590b2eaac3Santon     max = -1;
1600b2eaac3Santon     for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
1610b2eaac3Santon 	if (fd == fds[i])
1620b2eaac3Santon 	    return (0);
1630b2eaac3Santon 	if (fds[i] > max)
1640b2eaac3Santon 	    max = fds[i];
1650b2eaac3Santon     }
1660b2eaac3Santon     if (fd > max)
1670b2eaac3Santon 	return (1);
1680b2eaac3Santon 
1690b2eaac3Santon     return (-1);
1700b2eaac3Santon }
1710b2eaac3Santon 
1720b2eaac3Santon /*
173df930be7Sderaadt  * This routine is called after an error to close up
174df930be7Sderaadt  * any units which may have been left open accidentally.
175df930be7Sderaadt  */
176df930be7Sderaadt void
closem(void)177e757c91eSderaadt closem(void)
178df930be7Sderaadt {
179e757c91eSderaadt     int f;
180adf3ff49Sguenther     int max = sysconf(_SC_OPEN_MAX);
181df930be7Sderaadt 
182adf3ff49Sguenther     for (f = 0; f < max; f++)
1830b2eaac3Santon 	switch (fdcmp(f)) {
1840b2eaac3Santon 	case 0:
1850b2eaac3Santon 	    continue;
1860b2eaac3Santon 	case 1:
1870b2eaac3Santon 	    closefrom(f);
1880b2eaac3Santon 	    return;
1890b2eaac3Santon 	default:
1900b2eaac3Santon 	    close(f);
1910b2eaac3Santon 	}
192df930be7Sderaadt }
193df930be7Sderaadt 
194df930be7Sderaadt void
donefds(void)195e757c91eSderaadt donefds(void)
196df930be7Sderaadt {
197df930be7Sderaadt     (void) close(0);
198df930be7Sderaadt     (void) close(1);
199df930be7Sderaadt     (void) close(2);
200df930be7Sderaadt 
201df930be7Sderaadt     didfds = 0;
202df930be7Sderaadt }
203df930be7Sderaadt 
204df930be7Sderaadt /*
205df930be7Sderaadt  * Move descriptor i to j.
206df930be7Sderaadt  * If j is -1 then we just want to get i to a safe place,
207df930be7Sderaadt  * i.e. to a unit > 2.  This also happens in dcopy.
208df930be7Sderaadt  */
209df930be7Sderaadt int
dmove(int i,int j)210e757c91eSderaadt dmove(int i, int j)
211df930be7Sderaadt {
212df930be7Sderaadt 
213df930be7Sderaadt     if (i == j || i < 0)
214df930be7Sderaadt 	return (i);
215df930be7Sderaadt     if (j >= 0) {
216df930be7Sderaadt 	(void) dup2(i, j);
217df930be7Sderaadt 	if (j != i)
218df930be7Sderaadt 	    (void) close(i);
219df930be7Sderaadt 	return (j);
220df930be7Sderaadt     }
221df930be7Sderaadt     j = dcopy(i, j);
222df930be7Sderaadt     if (j != i)
223df930be7Sderaadt 	(void) close(i);
224df930be7Sderaadt     return (j);
225df930be7Sderaadt }
226df930be7Sderaadt 
227df930be7Sderaadt int
dcopy(int i,int j)228e757c91eSderaadt dcopy(int i, int j)
229df930be7Sderaadt {
230df930be7Sderaadt 
231df930be7Sderaadt     if (i == j || i < 0 || (j < 0 && i > 2))
232df930be7Sderaadt 	return (i);
233df930be7Sderaadt     if (j >= 0) {
234df930be7Sderaadt 	(void) dup2(i, j);
235df930be7Sderaadt 	return (j);
236df930be7Sderaadt     }
237df930be7Sderaadt     (void) close(j);
238df930be7Sderaadt     return (renum(i, j));
239df930be7Sderaadt }
240df930be7Sderaadt 
241df930be7Sderaadt static int
renum(int i,int j)242e757c91eSderaadt renum(int i, int j)
243df930be7Sderaadt {
244e757c91eSderaadt     int k = dup(i);
245df930be7Sderaadt 
246df930be7Sderaadt     if (k < 0)
247df930be7Sderaadt 	return (-1);
248df930be7Sderaadt     if (j == -1 && k > 2)
249df930be7Sderaadt 	return (k);
250df930be7Sderaadt     if (k != j) {
251df930be7Sderaadt 	j = renum(k, j);
252df930be7Sderaadt 	(void) close(k);
253df930be7Sderaadt 	return (j);
254df930be7Sderaadt     }
255df930be7Sderaadt     return (k);
256df930be7Sderaadt }
257df930be7Sderaadt 
258df930be7Sderaadt /*
259df930be7Sderaadt  * Left shift a command argument list, discarding
260df930be7Sderaadt  * the first c arguments.  Used in "shift" commands
261df930be7Sderaadt  * as well as by commands like "repeat".
262df930be7Sderaadt  */
263df930be7Sderaadt void
lshift(Char ** v,int c)264e757c91eSderaadt lshift(Char **v, int c)
265df930be7Sderaadt {
266e757c91eSderaadt     Char **u;
267df930be7Sderaadt 
268df930be7Sderaadt     for (u = v; *u && --c >= 0; u++)
269acdb3202Smestre 	free(*u);
270df930be7Sderaadt     (void) blkcpy(v, u);
271df930be7Sderaadt }
272df930be7Sderaadt 
273df930be7Sderaadt int
number(Char * cp)274e757c91eSderaadt number(Char *cp)
275df930be7Sderaadt {
276df930be7Sderaadt     if (!cp)
277df930be7Sderaadt 	return(0);
278df930be7Sderaadt     if (*cp == '-') {
279df930be7Sderaadt 	cp++;
280df930be7Sderaadt 	if (!Isdigit(*cp))
281df930be7Sderaadt 	    return (0);
282df930be7Sderaadt 	cp++;
283df930be7Sderaadt     }
284df930be7Sderaadt     while (*cp && Isdigit(*cp))
285df930be7Sderaadt 	cp++;
286df930be7Sderaadt     return (*cp == 0);
287df930be7Sderaadt }
288df930be7Sderaadt 
289df930be7Sderaadt Char  **
copyblk(Char ** v)290e757c91eSderaadt copyblk(Char **v)
291df930be7Sderaadt {
292*d95322bbSmartijn     Char  **nv = xcalloc(blklen(v) + 1, sizeof(*nv));
293df930be7Sderaadt 
294df930be7Sderaadt     return (blkcpy(nv, v));
295df930be7Sderaadt }
296df930be7Sderaadt 
297df930be7Sderaadt Char   *
strip(Char * cp)298e757c91eSderaadt strip(Char *cp)
299df930be7Sderaadt {
300e757c91eSderaadt     Char *dp = cp;
301df930be7Sderaadt 
302df930be7Sderaadt     if (!cp)
303df930be7Sderaadt 	return (cp);
304df930be7Sderaadt     while ((*dp++ &= TRIM) != '\0')
305df930be7Sderaadt 	continue;
306df930be7Sderaadt     return (cp);
307df930be7Sderaadt }
308df930be7Sderaadt 
3096b38f156Smillert Char   *
quote(Char * cp)310e757c91eSderaadt quote(Char *cp)
3116b38f156Smillert {
312e757c91eSderaadt     Char *dp = cp;
3136b38f156Smillert 
3146b38f156Smillert     if (!cp)
3156b38f156Smillert 	return (cp);
3166b38f156Smillert     while (*dp != '\0')
3176b38f156Smillert 	*dp++ |= QUOTE;
3186b38f156Smillert     return (cp);
3196b38f156Smillert }
3206b38f156Smillert 
321df930be7Sderaadt void
udvar(Char * name)322e757c91eSderaadt udvar(Char *name)
323df930be7Sderaadt {
324df930be7Sderaadt 
325df930be7Sderaadt     setname(vis_str(name));
326df930be7Sderaadt     stderror(ERR_NAME | ERR_UNDVAR);
327df930be7Sderaadt }
328df930be7Sderaadt 
329df930be7Sderaadt int
prefix(Char * sub,Char * str)330e757c91eSderaadt prefix(Char *sub, Char *str)
331df930be7Sderaadt {
332df930be7Sderaadt 
333df930be7Sderaadt     for (;;) {
334df930be7Sderaadt 	if (*sub == 0)
335df930be7Sderaadt 	    return (1);
336df930be7Sderaadt 	if (*str == 0)
337df930be7Sderaadt 	    return (0);
338df930be7Sderaadt 	if (*sub++ != *str++)
339df930be7Sderaadt 	    return (0);
340df930be7Sderaadt     }
341df930be7Sderaadt }
342