Home | History | Annotate | Line # | Download | only in csh
misc.c revision 1.15
      1 /* $NetBSD: misc.c,v 1.15 2004/01/05 23:12:30 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.15 2004/01/05 23:12:30 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(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(char *s)
     67 {
     68     char *n, *p;
     69 
     70     if (s == NULL)
     71 	s = "";
     72     for (p = s; *p++;)
     73 	continue;
     74     n = p = (char *)xmalloc((size_t)((p - s) * sizeof(char)));
     75     while ((*p++ = *s++) != '\0')
     76 	continue;
     77     return (n);
     78 }
     79 
     80 Char **
     81 blkend(Char **up)
     82 {
     83     while (*up)
     84 	up++;
     85     return (up);
     86 }
     87 
     88 
     89 void
     90 blkpr(FILE *fp, Char **av)
     91 {
     92     for (; *av; av++) {
     93 	(void)fprintf(fp, "%s", vis_str(*av));
     94 	if (av[1])
     95 	    (void)fprintf(fp, " ");
     96     }
     97 }
     98 
     99 int
    100 blklen(Char **av)
    101 {
    102     int i;
    103 
    104     i = 0;
    105     while (*av++)
    106 	i++;
    107     return (i);
    108 }
    109 
    110 Char **
    111 blkcpy(Char **oav, Char **bv)
    112 {
    113     Char **av;
    114 
    115     av = oav;
    116     while ((*av++ = *bv++) != NULL)
    117 	continue;
    118     return (oav);
    119 }
    120 
    121 Char **
    122 blkcat(Char **up, Char **vp)
    123 {
    124     (void)blkcpy(blkend(up), vp);
    125     return (up);
    126 }
    127 
    128 void
    129 blkfree(Char **av0)
    130 {
    131     Char **av;
    132 
    133     av = av0;
    134     if (!av0)
    135 	return;
    136     for (; *av; av++)
    137 	xfree((ptr_t) * av);
    138     xfree((ptr_t) av0);
    139 }
    140 
    141 Char **
    142 saveblk(Char **v)
    143 {
    144     Char **newv, **onewv;
    145 
    146     newv = (Char **)xcalloc((size_t)(blklen(v) + 1), sizeof(Char **));
    147     onewv = newv;
    148     while (*v)
    149 	*newv++ = Strsave(*v++);
    150     return (onewv);
    151 }
    152 
    153 #ifdef NOTUSED
    154 char *
    155 strstr(char *s, char *t)
    156 {
    157     do {
    158 	char *ss;
    159 	char *tt;
    160 
    161 	ss = s;
    162 	tt = t;
    163 
    164 	do
    165 	    if (*tt == '\0')
    166 		return (s);
    167 	while (*ss++ == *tt++);
    168     } while (*s++ != '\0');
    169     return (NULL);
    170 }
    171 
    172 #endif /* NOTUSED */
    173 
    174 #ifndef SHORT_STRINGS
    175 char *
    176 strspl(char *cp, char *dp)
    177 {
    178     char *ep, *p, *q;
    179 
    180     if (!cp)
    181 	cp = "";
    182     if (!dp)
    183 	dp = "";
    184     for (p = cp; *p++;)
    185 	continue;
    186     for (q = dp; *q++;)
    187 	continue;
    188     ep = (char *) xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(char)));
    189     for (p = ep, q = cp; *p++ = *q++;)
    190 	continue;
    191     for (p--, q = dp; *p++ = *q++;)
    192 	continue;
    193     return (ep);
    194 }
    195 
    196 #endif
    197 
    198 Char **
    199 blkspl(Char **up, Char **vp)
    200 {
    201     Char **wp;
    202 
    203     wp = (Char **)xcalloc((size_t)(blklen(up) + blklen(vp) + 1),
    204         sizeof(Char **));
    205     (void)blkcpy(wp, up);
    206     return (blkcat(wp, vp));
    207 }
    208 
    209 Char
    210 lastchr(Char *cp)
    211 {
    212     if (!cp)
    213 	return (0);
    214     if (!*cp)
    215 	return (0);
    216     while (cp[1])
    217 	cp++;
    218     return (*cp);
    219 }
    220 
    221 /*
    222  * This routine is called after an error to close up
    223  * any units which may have been left open accidentally.
    224  */
    225 void
    226 closem(void)
    227 {
    228     int f;
    229     int nofile;
    230 
    231 #ifdef F_CLOSEM
    232     nofile = FOLDSTD + 1;
    233     if (fcntl(nofile, F_CLOSEM, 0) == -1)
    234 	stderror(ERR_SYSTEM, "", strerror(errno));
    235 #else
    236     nofile = NOFILE;
    237 #endif
    238 
    239     for (f = 0; f < nofile; f++)
    240 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
    241 	    f != FSHTTY)
    242 	    (void) close(f);
    243 }
    244 
    245 void
    246 donefds(void)
    247 {
    248     (void)close(0);
    249     (void)close(1);
    250     (void)close(2);
    251 
    252     didfds = 0;
    253 }
    254 
    255 /*
    256  * Move descriptor i to j.
    257  * If j is -1 then we just want to get i to a safe place,
    258  * i.e. to a unit > 2.  This also happens in dcopy.
    259  */
    260 int
    261 dmove(int i, int j)
    262 {
    263     if (i == j || i < 0)
    264 	return (i);
    265     if (j >= 0) {
    266 	(void)dup2(i, j);
    267 	if (j != i)
    268 	    (void)close(i);
    269 	return (j);
    270     }
    271     j = dcopy(i, j);
    272     if (j != i)
    273 	(void)close(i);
    274     return (j);
    275 }
    276 
    277 int
    278 dcopy(int i, int j)
    279 {
    280     if (i == j || i < 0 || (j < 0 && i > 2))
    281 	return (i);
    282     if (j >= 0) {
    283 	(void)dup2(i, j);
    284 	return (j);
    285     }
    286     (void)close(j);
    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, int 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 = (Char **)xcalloc((size_t)(blklen(v) + 1), sizeof(Char **));
    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