Home | History | Annotate | Line # | Download | only in csh
misc.c revision 1.16
      1 /* $NetBSD: misc.c,v 1.16 2004/01/06 00:20:16 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.16 2004/01/06 00:20:16 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 #endif
    235 	nofile = NOFILE;
    236 
    237     for (f = 0; f < nofile; f++)
    238 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
    239 	    f != FSHTTY)
    240 	    (void) close(f);
    241 }
    242 
    243 void
    244 donefds(void)
    245 {
    246     (void)close(0);
    247     (void)close(1);
    248     (void)close(2);
    249 
    250     didfds = 0;
    251 }
    252 
    253 /*
    254  * Move descriptor i to j.
    255  * If j is -1 then we just want to get i to a safe place,
    256  * i.e. to a unit > 2.  This also happens in dcopy.
    257  */
    258 int
    259 dmove(int i, int j)
    260 {
    261     if (i == j || i < 0)
    262 	return (i);
    263     if (j >= 0) {
    264 	(void)dup2(i, j);
    265 	if (j != i)
    266 	    (void)close(i);
    267 	return (j);
    268     }
    269     j = dcopy(i, j);
    270     if (j != i)
    271 	(void)close(i);
    272     return (j);
    273 }
    274 
    275 int
    276 dcopy(int i, int j)
    277 {
    278     if (i == j || i < 0 || (j < 0 && i > 2))
    279 	return (i);
    280     if (j >= 0) {
    281 	(void)dup2(i, j);
    282 	return (j);
    283     }
    284     (void)close(j);
    285     return (renum(i, j));
    286 }
    287 
    288 static int
    289 renum(int i, int j)
    290 {
    291     int k;
    292 
    293     k = dup(i);
    294     if (k < 0)
    295 	return (-1);
    296     if (j == -1 && k > 2)
    297 	return (k);
    298     if (k != j) {
    299 	j = renum(k, j);
    300 	(void)close(k);
    301 	return (j);
    302     }
    303     return (k);
    304 }
    305 
    306 /*
    307  * Left shift a command argument list, discarding
    308  * the first c arguments.  Used in "shift" commands
    309  * as well as by commands like "repeat".
    310  */
    311 void
    312 lshift(Char **v, int c)
    313 {
    314     Char **u;
    315 
    316     for (u = v; *u && --c >= 0; u++)
    317 	xfree((ptr_t) *u);
    318     (void)blkcpy(v, u);
    319 }
    320 
    321 int
    322 number(Char *cp)
    323 {
    324     if (!cp)
    325 	return(0);
    326     if (*cp == '-') {
    327 	cp++;
    328 	if (!Isdigit(*cp))
    329 	    return (0);
    330 	cp++;
    331     }
    332     while (*cp && Isdigit(*cp))
    333 	cp++;
    334     return (*cp == 0);
    335 }
    336 
    337 Char **
    338 copyblk(Char **v)
    339 {
    340     Char **nv;
    341 
    342     nv = (Char **)xcalloc((size_t)(blklen(v) + 1), sizeof(Char **));
    343 
    344     return (blkcpy(nv, v));
    345 }
    346 
    347 #ifndef SHORT_STRINGS
    348 char *
    349 strend(char *cp)
    350 {
    351     if (!cp)
    352 	return (cp);
    353     while (*cp)
    354 	cp++;
    355     return (cp);
    356 }
    357 
    358 #endif /* SHORT_STRINGS */
    359 
    360 Char *
    361 strip(Char *cp)
    362 {
    363     Char *dp;
    364 
    365     dp = cp;
    366     if (!cp)
    367 	return (cp);
    368     while ((*dp++ &= TRIM) != '\0')
    369 	continue;
    370     return (cp);
    371 }
    372 
    373 Char *
    374 quote(Char *cp)
    375 {
    376     Char *dp;
    377 
    378     dp = cp;
    379     if (!cp)
    380 	return (cp);
    381     while (*dp != '\0')
    382 	*dp++ |= QUOTE;
    383     return (cp);
    384 }
    385 
    386 void
    387 udvar(Char *name)
    388 {
    389     setname(vis_str(name));
    390     stderror(ERR_NAME | ERR_UNDVAR);
    391     /* NOTREACHED */
    392 }
    393 
    394 int
    395 prefix(Char *sub, Char *str)
    396 {
    397     for (;;) {
    398 	if (*sub == 0)
    399 	    return (1);
    400 	if (*str == 0)
    401 	    return (0);
    402 	if (*sub++ != *str++)
    403 	    return (0);
    404     }
    405 }
    406