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