Home | History | Annotate | Line # | Download | only in csh
      1 /* $NetBSD: misc.c,v 1.23 2024/04/24 15:49:03 nia 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.23 2024/04/24 15:49:03 nia 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 = xreallocarray(NULL, (size_t)(n - s), sizeof(*p));
     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 	free(* av);
    139     free(av0);
    140 }
    141 
    142 Char **
    143 saveblk(Char **v)
    144 {
    145     Char **newv, **onewv;
    146 
    147     if (v == NULL)
    148 	return NULL;
    149 
    150     newv = xcalloc((size_t)(blklen(v) + 1), sizeof(*newv));
    151     onewv = newv;
    152     while (*v)
    153 	*newv++ = Strsave(*v++);
    154     return (onewv);
    155 }
    156 
    157 #ifdef NOTUSED
    158 char *
    159 strstr(char *s, char *t)
    160 {
    161     do {
    162 	char *ss;
    163 	char *tt;
    164 
    165 	ss = s;
    166 	tt = t;
    167 
    168 	do
    169 	    if (*tt == '\0')
    170 		return (s);
    171 	while (*ss++ == *tt++);
    172     } while (*s++ != '\0');
    173     return (NULL);
    174 }
    175 
    176 #endif /* NOTUSED */
    177 
    178 #ifndef SHORT_STRINGS
    179 char *
    180 strspl(char *cp, char *dp)
    181 {
    182     char *ep, *p, *q;
    183 
    184     if (!cp)
    185 	cp = "";
    186     if (!dp)
    187 	dp = "";
    188     for (p = cp; *p++;)
    189 	continue;
    190     for (q = dp; *q++;)
    191 	continue;
    192     ep = xreallocarray(NULL, (size_t)(((p - cp) + (q - dp) - 1), sizeof(*ep)));
    193     for (p = ep, q = cp; *p++ = *q++;)
    194 	continue;
    195     for (p--, q = dp; *p++ = *q++;)
    196 	continue;
    197     return (ep);
    198 }
    199 
    200 #endif
    201 
    202 Char **
    203 blkspl(Char **up, Char **vp)
    204 {
    205     Char **wp;
    206 
    207     wp = xcalloc((size_t)(blklen(up) + blklen(vp) + 1), sizeof(*wp));
    208     (void)blkcpy(wp, up);
    209     return (blkcat(wp, vp));
    210 }
    211 
    212 Char
    213 lastchr(Char *cp)
    214 {
    215     if (!cp)
    216 	return (0);
    217     if (!*cp)
    218 	return (0);
    219     while (cp[1])
    220 	cp++;
    221     return (*cp);
    222 }
    223 
    224 /*
    225  * This routine is called after an error to close up
    226  * any units which may have been left open accidentally.
    227  */
    228 void
    229 closem(void)
    230 {
    231     int f;
    232     int nofile;
    233 
    234 #ifdef F_CLOSEM
    235     nofile = FOLDSTD + 1;
    236     if (fcntl(nofile, F_CLOSEM, 0) == -1)
    237 #endif
    238 	nofile = NOFILE;
    239 
    240     for (f = 0; f < nofile; f++)
    241 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
    242 	    f != FSHTTY)
    243 	    (void) close(f);
    244 }
    245 
    246 void
    247 donefds(void)
    248 {
    249     (void)close(0);
    250     (void)close(1);
    251     (void)close(2);
    252 
    253     didfds = 0;
    254 }
    255 
    256 /*
    257  * Move descriptor i to j.
    258  * If j is -1 then we just want to get i to a safe place,
    259  * i.e. to a unit > 2.  This also happens in dcopy.
    260  */
    261 int
    262 dmove(int i, int j)
    263 {
    264     if (i == j || i < 0)
    265 	return (i);
    266     if (j >= 0) {
    267 	(void)dup2(i, j);
    268 	if (j != i)
    269 	    (void)close(i);
    270 	return (j);
    271     }
    272     j = dcopy(i, j);
    273     if (j != i)
    274 	(void)close(i);
    275     return (j);
    276 }
    277 
    278 int
    279 dcopy(int i, int j)
    280 {
    281     if (i == j || i < 0 || (j < 0 && i > 2))
    282 	return (i);
    283     if (j >= 0) {
    284 	(void)dup2(i, j);
    285 	return (j);
    286     }
    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, size_t c)
    315 {
    316     Char **u;
    317 
    318     for (u = v; *u && c-- > 0; u++)
    319 	free(*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 = xcalloc((size_t)(blklen(v) + 1), sizeof(*nv));
    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