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