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