xref: /minix/bin/csh/misc.c (revision 0a6a1f1d)
1 /* $NetBSD: misc.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 1980, 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)misc.c	8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: misc.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include <sys/param.h>
42 
43 #include <stdarg.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 
49 #include "csh.h"
50 #include "extern.h"
51 
52 static int renum(int, int);
53 
54 int
55 any(const char *s, int c)
56 {
57     if (!s)
58 	return (0);		/* Check for nil pointer */
59     while (*s)
60 	if (*s++ == c)
61 	    return (1);
62     return (0);
63 }
64 
65 char *
66 strsave(const char *s)
67 {
68     const char *n;
69     char *p, *r;
70 
71     if (s == NULL)
72 	s = "";
73     for (n = s; *n++;)
74 	continue;
75     r = p = xmalloc((size_t)(n - s) * sizeof(*p));
76     while ((*p++ = *s++) != '\0')
77 	continue;
78     return (r);
79 }
80 
81 Char **
82 blkend(Char **up)
83 {
84     while (*up)
85 	up++;
86     return (up);
87 }
88 
89 
90 void
91 blkpr(FILE *fp, Char **av)
92 {
93     for (; *av; av++) {
94 	(void)fprintf(fp, "%s", vis_str(*av));
95 	if (av[1])
96 	    (void)fprintf(fp, " ");
97     }
98 }
99 
100 int
101 blklen(Char **av)
102 {
103     int i;
104 
105     i = 0;
106     while (*av++)
107 	i++;
108     return (i);
109 }
110 
111 Char **
112 blkcpy(Char **oav, Char **bv)
113 {
114     Char **av;
115 
116     av = oav;
117     while ((*av++ = *bv++) != NULL)
118 	continue;
119     return (oav);
120 }
121 
122 Char **
123 blkcat(Char **up, Char **vp)
124 {
125     (void)blkcpy(blkend(up), vp);
126     return (up);
127 }
128 
129 void
130 blkfree(Char **av0)
131 {
132     Char **av;
133 
134     av = av0;
135     if (!av0)
136 	return;
137     for (; *av; av++)
138 	xfree((ptr_t) * av);
139     xfree((ptr_t) av0);
140 }
141 
142 Char **
143 saveblk(Char **v)
144 {
145     Char **newv, **onewv;
146 
147     if (v == NULL)
148 	return NULL;
149 
150     newv = xcalloc((size_t)(blklen(v) + 1), sizeof(*newv));
151     onewv = newv;
152     while (*v)
153 	*newv++ = Strsave(*v++);
154     return (onewv);
155 }
156 
157 #ifdef NOTUSED
158 char *
159 strstr(char *s, char *t)
160 {
161     do {
162 	char *ss;
163 	char *tt;
164 
165 	ss = s;
166 	tt = t;
167 
168 	do
169 	    if (*tt == '\0')
170 		return (s);
171 	while (*ss++ == *tt++);
172     } while (*s++ != '\0');
173     return (NULL);
174 }
175 
176 #endif /* NOTUSED */
177 
178 #ifndef SHORT_STRINGS
179 char *
180 strspl(char *cp, char *dp)
181 {
182     char *ep, *p, *q;
183 
184     if (!cp)
185 	cp = "";
186     if (!dp)
187 	dp = "";
188     for (p = cp; *p++;)
189 	continue;
190     for (q = dp; *q++;)
191 	continue;
192     ep = xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(*ep)));
193     for (p = ep, q = cp; *p++ = *q++;)
194 	continue;
195     for (p--, q = dp; *p++ = *q++;)
196 	continue;
197     return (ep);
198 }
199 
200 #endif
201 
202 Char **
203 blkspl(Char **up, Char **vp)
204 {
205     Char **wp;
206 
207     wp = xcalloc((size_t)(blklen(up) + blklen(vp) + 1), sizeof(*wp));
208     (void)blkcpy(wp, up);
209     return (blkcat(wp, vp));
210 }
211 
212 Char
213 lastchr(Char *cp)
214 {
215     if (!cp)
216 	return (0);
217     if (!*cp)
218 	return (0);
219     while (cp[1])
220 	cp++;
221     return (*cp);
222 }
223 
224 /*
225  * This routine is called after an error to close up
226  * any units which may have been left open accidentally.
227  */
228 void
229 closem(void)
230 {
231     int f;
232     int nofile;
233 
234 #ifdef F_CLOSEM
235     nofile = FOLDSTD + 1;
236     if (fcntl(nofile, F_CLOSEM, 0) == -1)
237 #endif
238 	nofile = NOFILE;
239 
240     for (f = 0; f < nofile; f++)
241 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
242 	    f != FSHTTY)
243 	    (void) close(f);
244 }
245 
246 void
247 donefds(void)
248 {
249     (void)close(0);
250     (void)close(1);
251     (void)close(2);
252 
253     didfds = 0;
254 }
255 
256 /*
257  * Move descriptor i to j.
258  * If j is -1 then we just want to get i to a safe place,
259  * i.e. to a unit > 2.  This also happens in dcopy.
260  */
261 int
262 dmove(int i, int j)
263 {
264     if (i == j || i < 0)
265 	return (i);
266     if (j >= 0) {
267 	(void)dup2(i, j);
268 	if (j != i)
269 	    (void)close(i);
270 	return (j);
271     }
272     j = dcopy(i, j);
273     if (j != i)
274 	(void)close(i);
275     return (j);
276 }
277 
278 int
279 dcopy(int i, int j)
280 {
281     if (i == j || i < 0 || (j < 0 && i > 2))
282 	return (i);
283     if (j >= 0) {
284 	(void)dup2(i, j);
285 	return (j);
286     }
287     return (renum(i, j));
288 }
289 
290 static int
291 renum(int i, int j)
292 {
293     int k;
294 
295     k = dup(i);
296     if (k < 0)
297 	return (-1);
298     if (j == -1 && k > 2)
299 	return (k);
300     if (k != j) {
301 	j = renum(k, j);
302 	(void)close(k);
303 	return (j);
304     }
305     return (k);
306 }
307 
308 /*
309  * Left shift a command argument list, discarding
310  * the first c arguments.  Used in "shift" commands
311  * as well as by commands like "repeat".
312  */
313 void
314 lshift(Char **v, size_t c)
315 {
316     Char **u;
317 
318     for (u = v; *u && c-- > 0; u++)
319 	xfree((ptr_t) *u);
320     (void)blkcpy(v, u);
321 }
322 
323 int
324 number(Char *cp)
325 {
326     if (!cp)
327 	return(0);
328     if (*cp == '-') {
329 	cp++;
330 	if (!Isdigit(*cp))
331 	    return (0);
332 	cp++;
333     }
334     while (*cp && Isdigit(*cp))
335 	cp++;
336     return (*cp == 0);
337 }
338 
339 Char **
340 copyblk(Char **v)
341 {
342     Char **nv;
343 
344     nv = xcalloc((size_t)(blklen(v) + 1), sizeof(*nv));
345 
346     return (blkcpy(nv, v));
347 }
348 
349 #ifndef SHORT_STRINGS
350 char *
351 strend(char *cp)
352 {
353     if (!cp)
354 	return (cp);
355     while (*cp)
356 	cp++;
357     return (cp);
358 }
359 
360 #endif /* SHORT_STRINGS */
361 
362 Char *
363 strip(Char *cp)
364 {
365     Char *dp;
366 
367     dp = cp;
368     if (!cp)
369 	return (cp);
370     while ((*dp++ &= TRIM) != '\0')
371 	continue;
372     return (cp);
373 }
374 
375 Char *
376 quote(Char *cp)
377 {
378     Char *dp;
379 
380     dp = cp;
381     if (!cp)
382 	return (cp);
383     while (*dp != '\0')
384 	*dp++ |= QUOTE;
385     return (cp);
386 }
387 
388 void
389 udvar(Char *name)
390 {
391     setname(vis_str(name));
392     stderror(ERR_NAME | ERR_UNDVAR);
393     /* NOTREACHED */
394 }
395 
396 int
397 prefix(Char *sub, Char *str)
398 {
399     for (;;) {
400 	if (*sub == 0)
401 	    return (1);
402 	if (*str == 0)
403 	    return (0);
404 	if (*sub++ != *str++)
405 	    return (0);
406     }
407 }
408