Home | History | Annotate | Line # | Download | only in csh
misc.c revision 1.17
      1 /* $NetBSD: misc.c,v 1.17 2005/06/26 19:10:48 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.17 2005/06/26 19:10:48 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 = (char *)xmalloc((size_t)((n - s) * sizeof(char)));
     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     newv = (Char **)xcalloc((size_t)(blklen(v) + 1), sizeof(Char **));
    148     onewv = newv;
    149     while (*v)
    150 	*newv++ = Strsave(*v++);
    151     return (onewv);
    152 }
    153 
    154 #ifdef NOTUSED
    155 char *
    156 strstr(char *s, char *t)
    157 {
    158     do {
    159 	char *ss;
    160 	char *tt;
    161 
    162 	ss = s;
    163 	tt = t;
    164 
    165 	do
    166 	    if (*tt == '\0')
    167 		return (s);
    168 	while (*ss++ == *tt++);
    169     } while (*s++ != '\0');
    170     return (NULL);
    171 }
    172 
    173 #endif /* NOTUSED */
    174 
    175 #ifndef SHORT_STRINGS
    176 char *
    177 strspl(char *cp, char *dp)
    178 {
    179     char *ep, *p, *q;
    180 
    181     if (!cp)
    182 	cp = "";
    183     if (!dp)
    184 	dp = "";
    185     for (p = cp; *p++;)
    186 	continue;
    187     for (q = dp; *q++;)
    188 	continue;
    189     ep = (char *) xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(char)));
    190     for (p = ep, q = cp; *p++ = *q++;)
    191 	continue;
    192     for (p--, q = dp; *p++ = *q++;)
    193 	continue;
    194     return (ep);
    195 }
    196 
    197 #endif
    198 
    199 Char **
    200 blkspl(Char **up, Char **vp)
    201 {
    202     Char **wp;
    203 
    204     wp = (Char **)xcalloc((size_t)(blklen(up) + blklen(vp) + 1),
    205         sizeof(Char **));
    206     (void)blkcpy(wp, up);
    207     return (blkcat(wp, vp));
    208 }
    209 
    210 Char
    211 lastchr(Char *cp)
    212 {
    213     if (!cp)
    214 	return (0);
    215     if (!*cp)
    216 	return (0);
    217     while (cp[1])
    218 	cp++;
    219     return (*cp);
    220 }
    221 
    222 /*
    223  * This routine is called after an error to close up
    224  * any units which may have been left open accidentally.
    225  */
    226 void
    227 closem(void)
    228 {
    229     int f;
    230     int nofile;
    231 
    232 #ifdef F_CLOSEM
    233     nofile = FOLDSTD + 1;
    234     if (fcntl(nofile, F_CLOSEM, 0) == -1)
    235 #endif
    236 	nofile = NOFILE;
    237 
    238     for (f = 0; f < nofile; f++)
    239 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
    240 	    f != FSHTTY)
    241 	    (void) close(f);
    242 }
    243 
    244 void
    245 donefds(void)
    246 {
    247     (void)close(0);
    248     (void)close(1);
    249     (void)close(2);
    250 
    251     didfds = 0;
    252 }
    253 
    254 /*
    255  * Move descriptor i to j.
    256  * If j is -1 then we just want to get i to a safe place,
    257  * i.e. to a unit > 2.  This also happens in dcopy.
    258  */
    259 int
    260 dmove(int i, int j)
    261 {
    262     if (i == j || i < 0)
    263 	return (i);
    264     if (j >= 0) {
    265 	(void)dup2(i, j);
    266 	if (j != i)
    267 	    (void)close(i);
    268 	return (j);
    269     }
    270     j = dcopy(i, j);
    271     if (j != i)
    272 	(void)close(i);
    273     return (j);
    274 }
    275 
    276 int
    277 dcopy(int i, int j)
    278 {
    279     if (i == j || i < 0 || (j < 0 && i > 2))
    280 	return (i);
    281     if (j >= 0) {
    282 	(void)dup2(i, j);
    283 	return (j);
    284     }
    285     (void)close(j);
    286     return (renum(i, j));
    287 }
    288 
    289 static int
    290 renum(int i, int j)
    291 {
    292     int k;
    293 
    294     k = dup(i);
    295     if (k < 0)
    296 	return (-1);
    297     if (j == -1 && k > 2)
    298 	return (k);
    299     if (k != j) {
    300 	j = renum(k, j);
    301 	(void)close(k);
    302 	return (j);
    303     }
    304     return (k);
    305 }
    306 
    307 /*
    308  * Left shift a command argument list, discarding
    309  * the first c arguments.  Used in "shift" commands
    310  * as well as by commands like "repeat".
    311  */
    312 void
    313 lshift(Char **v, int c)
    314 {
    315     Char **u;
    316 
    317     for (u = v; *u && --c >= 0; u++)
    318 	xfree((ptr_t) *u);
    319     (void)blkcpy(v, u);
    320 }
    321 
    322 int
    323 number(Char *cp)
    324 {
    325     if (!cp)
    326 	return(0);
    327     if (*cp == '-') {
    328 	cp++;
    329 	if (!Isdigit(*cp))
    330 	    return (0);
    331 	cp++;
    332     }
    333     while (*cp && Isdigit(*cp))
    334 	cp++;
    335     return (*cp == 0);
    336 }
    337 
    338 Char **
    339 copyblk(Char **v)
    340 {
    341     Char **nv;
    342 
    343     nv = (Char **)xcalloc((size_t)(blklen(v) + 1), sizeof(Char **));
    344 
    345     return (blkcpy(nv, v));
    346 }
    347 
    348 #ifndef SHORT_STRINGS
    349 char *
    350 strend(char *cp)
    351 {
    352     if (!cp)
    353 	return (cp);
    354     while (*cp)
    355 	cp++;
    356     return (cp);
    357 }
    358 
    359 #endif /* SHORT_STRINGS */
    360 
    361 Char *
    362 strip(Char *cp)
    363 {
    364     Char *dp;
    365 
    366     dp = cp;
    367     if (!cp)
    368 	return (cp);
    369     while ((*dp++ &= TRIM) != '\0')
    370 	continue;
    371     return (cp);
    372 }
    373 
    374 Char *
    375 quote(Char *cp)
    376 {
    377     Char *dp;
    378 
    379     dp = cp;
    380     if (!cp)
    381 	return (cp);
    382     while (*dp != '\0')
    383 	*dp++ |= QUOTE;
    384     return (cp);
    385 }
    386 
    387 void
    388 udvar(Char *name)
    389 {
    390     setname(vis_str(name));
    391     stderror(ERR_NAME | ERR_UNDVAR);
    392     /* NOTREACHED */
    393 }
    394 
    395 int
    396 prefix(Char *sub, Char *str)
    397 {
    398     for (;;) {
    399 	if (*sub == 0)
    400 	    return (1);
    401 	if (*str == 0)
    402 	    return (0);
    403 	if (*sub++ != *str++)
    404 	    return (0);
    405     }
    406 }
    407