147823Sbostic /*- 247823Sbostic * Copyright (c) 1980, 1991 The Regents of the University of California. 347823Sbostic * All rights reserved. 447823Sbostic * 547823Sbostic * %sccs.include.redist.c% 621938Sdist */ 721938Sdist 817511Sedward #ifndef lint 9*50976Schristos static char sccsid[] = "@(#)misc.c 5.15 (Berkeley) 09/04/91"; 1047823Sbostic #endif /* not lint */ 111300Sbill 1250028Sbostic #include <sys/param.h> 1350028Sbostic #include <stdlib.h> 1450028Sbostic #include <unistd.h> 1550033Schristos #if __STDC__ 1650033Schristos # include <stdarg.h> 1750033Schristos #else 1850033Schristos # include <varargs.h> 1950033Schristos #endif 2050033Schristos 2150023Sbostic #include "csh.h" 2250023Sbostic #include "extern.h" 231300Sbill 2450024Schristos static int renum __P((int, int)); 251300Sbill 2649992Sbostic int 2749992Sbostic any(s, c) 2849992Sbostic register char *s; 2949992Sbostic register int c; 3017511Sedward { 3149992Sbostic if (!s) 3249992Sbostic return (0); /* Check for nil pointer */ 3349992Sbostic while (*s) 3449992Sbostic if (*s++ == c) 3549992Sbostic return (1); 3649992Sbostic return (0); 3717511Sedward } 3817511Sedward 3949992Sbostic void 4049992Sbostic setzero(cp, i) 4149992Sbostic char *cp; 4249992Sbostic int i; 4317511Sedward { 4449992Sbostic if (i != 0) 4549992Sbostic do 4649992Sbostic *cp++ = 0; 4749992Sbostic while (--i); 4817511Sedward } 4917511Sedward 5049992Sbostic char * 5149992Sbostic strsave(s) 5249992Sbostic register char *s; 5317511Sedward { 5449992Sbostic char *n; 5549992Sbostic register char *p; 5617511Sedward 5750023Sbostic if (s == NULL) 5849992Sbostic s = ""; 5949992Sbostic for (p = s; *p++;); 6049992Sbostic n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char))); 6149992Sbostic while (*p++ = *s++); 6249992Sbostic return (n); 6317511Sedward } 6417511Sedward 6549992Sbostic Char ** 6649992Sbostic blkend(up) 6749992Sbostic register Char **up; 681300Sbill { 691300Sbill 7049992Sbostic while (*up) 7149992Sbostic up++; 7249992Sbostic return (up); 731300Sbill } 741300Sbill 7517511Sedward 7649992Sbostic void 7750439Schristos blkpr(fp, av) 7850439Schristos FILE *fp; 7949992Sbostic register Char **av; 801300Sbill { 811300Sbill 8249992Sbostic for (; *av; av++) { 8350439Schristos (void) fprintf(fp, "%s", short2str(*av)); 8449992Sbostic if (av[1]) 8550439Schristos (void) fprintf(fp, " "); 8649992Sbostic } 871300Sbill } 881300Sbill 8949992Sbostic int 901300Sbill blklen(av) 9149992Sbostic register Char **av; 921300Sbill { 9349992Sbostic register int i = 0; 941300Sbill 9549992Sbostic while (*av++) 9649992Sbostic i++; 9749992Sbostic return (i); 981300Sbill } 991300Sbill 10049992Sbostic Char ** 1011300Sbill blkcpy(oav, bv) 10249992Sbostic Char **oav; 10349992Sbostic register Char **bv; 1041300Sbill { 10549992Sbostic register Char **av = oav; 1061300Sbill 10749992Sbostic while (*av++ = *bv++) 10849992Sbostic continue; 10949992Sbostic return (oav); 1101300Sbill } 1111300Sbill 11249992Sbostic Char ** 1131300Sbill blkcat(up, vp) 11449992Sbostic Char **up, **vp; 1151300Sbill { 1161300Sbill 11749992Sbostic (void) blkcpy(blkend(up), vp); 11849992Sbostic return (up); 1191300Sbill } 1201300Sbill 12149992Sbostic void 1221300Sbill blkfree(av0) 12349992Sbostic Char **av0; 1241300Sbill { 12549992Sbostic register Char **av = av0; 1261300Sbill 12749992Sbostic if (!av0) 12849992Sbostic return; 12949992Sbostic for (; *av; av++) 13049992Sbostic xfree((ptr_t) * av); 13149992Sbostic xfree((ptr_t) av0); 1321300Sbill } 1331300Sbill 13449992Sbostic Char ** 1351300Sbill saveblk(v) 13649992Sbostic register Char **v; 1371300Sbill { 13849992Sbostic register Char **newv = 13949992Sbostic (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 14049992Sbostic Char **onewv = newv; 1411300Sbill 14249992Sbostic while (*v) 14349992Sbostic *newv++ = Strsave(*v++); 14449992Sbostic return (onewv); 1451300Sbill } 1461300Sbill 14750011Schristos #ifdef NOTUSED 14849992Sbostic char * 14949992Sbostic strstr(s, t) 15049992Sbostic register char *s, *t; 15149992Sbostic { 15249992Sbostic do { 15349992Sbostic register char *ss = s; 15449992Sbostic register char *tt = t; 15549992Sbostic 15649992Sbostic do 15749992Sbostic if (*tt == '\0') 15849992Sbostic return (s); 15949992Sbostic while (*ss++ == *tt++); 16049992Sbostic } while (*s++ != '\0'); 16150024Schristos return (NULL); 16249992Sbostic } 16349992Sbostic 16450011Schristos #endif /* NOTUSED */ 16549992Sbostic 16649992Sbostic #ifndef SHORT_STRINGS 16749992Sbostic char * 1681300Sbill strspl(cp, dp) 16949992Sbostic char *cp, *dp; 1701300Sbill { 17149992Sbostic char *ep; 17249992Sbostic register char *p, *q; 1731300Sbill 17449992Sbostic if (!cp) 17549992Sbostic cp = ""; 17649992Sbostic if (!dp) 17749992Sbostic dp = ""; 17849992Sbostic for (p = cp; *p++;); 17949992Sbostic for (q = dp; *q++;); 18049992Sbostic ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char))); 18149992Sbostic for (p = ep, q = cp; *p++ = *q++;); 18249992Sbostic for (p--, q = dp; *p++ = *q++;); 18349992Sbostic return (ep); 1841300Sbill } 1851300Sbill 18649992Sbostic #endif 18749992Sbostic 18849992Sbostic Char ** 1891300Sbill blkspl(up, vp) 19049992Sbostic register Char **up, **vp; 1911300Sbill { 19249992Sbostic register Char **wp = 19349992Sbostic (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 19449992Sbostic sizeof(Char **)); 1951300Sbill 19649992Sbostic (void) blkcpy(wp, up); 19749992Sbostic return (blkcat(wp, vp)); 1981300Sbill } 1991300Sbill 20049992Sbostic Char 2011300Sbill lastchr(cp) 20249992Sbostic register Char *cp; 2031300Sbill { 2041300Sbill 20549992Sbostic if (!cp) 20649992Sbostic return (0); 20749992Sbostic if (!*cp) 20849992Sbostic return (0); 20949992Sbostic while (cp[1]) 21049992Sbostic cp++; 21149992Sbostic return (*cp); 2121300Sbill } 2131300Sbill 2141300Sbill /* 2151300Sbill * This routine is called after an error to close up 2161300Sbill * any units which may have been left open accidentally. 2171300Sbill */ 21849992Sbostic void 2191300Sbill closem() 2201300Sbill { 22149992Sbostic register int f; 2221300Sbill 22349992Sbostic for (f = 0; f < NOFILE; f++) 22450439Schristos if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 22549992Sbostic f != FSHTTY) 22649992Sbostic (void) close(f); 2271300Sbill } 2281300Sbill 22949992Sbostic void 2301300Sbill donefds() 2311300Sbill { 23249992Sbostic (void) close(0); 23349992Sbostic (void) close(1); 23449992Sbostic (void) close(2); 23550439Schristos 23649992Sbostic didfds = 0; 2371300Sbill } 2381300Sbill 2391300Sbill /* 2401300Sbill * Move descriptor i to j. 2411300Sbill * If j is -1 then we just want to get i to a safe place, 2421300Sbill * i.e. to a unit > 2. This also happens in dcopy. 2431300Sbill */ 24449992Sbostic int 2451300Sbill dmove(i, j) 24649992Sbostic register int i, j; 2471300Sbill { 2481300Sbill 24949992Sbostic if (i == j || i < 0) 25049992Sbostic return (i); 25149992Sbostic if (j >= 0) { 25249992Sbostic (void) dup2(i, j); 25350233Schristos if (j != i) 25450233Schristos (void) close(i); 2551300Sbill return (j); 25649992Sbostic } 25749992Sbostic j = dcopy(i, j); 25849992Sbostic if (j != i) 25949992Sbostic (void) close(i); 26049992Sbostic return (j); 2611300Sbill } 2621300Sbill 26349992Sbostic int 2641300Sbill dcopy(i, j) 26549992Sbostic register int i, j; 2661300Sbill { 2671300Sbill 26849992Sbostic if (i == j || i < 0 || j < 0 && i > 2) 26949992Sbostic return (i); 27049992Sbostic if (j >= 0) { 27149992Sbostic (void) dup2(i, j); 27249992Sbostic return (j); 27349992Sbostic } 27449992Sbostic (void) close(j); 27549992Sbostic return (renum(i, j)); 2761300Sbill } 2771300Sbill 27849992Sbostic static int 2791300Sbill renum(i, j) 28049992Sbostic register int i, j; 2811300Sbill { 28249992Sbostic register int k = dup(i); 2831300Sbill 28449992Sbostic if (k < 0) 28549992Sbostic return (-1); 28649992Sbostic if (j == -1 && k > 2) 2871300Sbill return (k); 28849992Sbostic if (k != j) { 28949992Sbostic j = renum(k, j); 29049992Sbostic (void) close(k); 29149992Sbostic return (j); 29249992Sbostic } 29349992Sbostic return (k); 2941300Sbill } 2951300Sbill 2961300Sbill /* 2971300Sbill * Left shift a command argument list, discarding 2981300Sbill * the first c arguments. Used in "shift" commands 2991300Sbill * as well as by commands like "repeat". 3001300Sbill */ 30149992Sbostic void 3021300Sbill lshift(v, c) 30349992Sbostic register Char **v; 30449992Sbostic register int c; 3051300Sbill { 306*50976Schristos register Char **u; 3071300Sbill 308*50976Schristos for (u = v; *u && --c >= 0; u++) 309*50976Schristos xfree((ptr_t) *u); 31049992Sbostic (void) blkcpy(v, u); 3111300Sbill } 3121300Sbill 31349992Sbostic int 3141300Sbill number(cp) 31549992Sbostic Char *cp; 3161300Sbill { 31749992Sbostic if (!cp) 31849992Sbostic return(0); 31949992Sbostic if (*cp == '-') { 32049992Sbostic cp++; 32149992Sbostic if (!Isdigit(*cp)) 32249992Sbostic return (0); 32349992Sbostic cp++; 32449992Sbostic } 32549992Sbostic while (*cp && Isdigit(*cp)) 32649992Sbostic cp++; 32749992Sbostic return (*cp == 0); 3281300Sbill } 3291300Sbill 33049992Sbostic Char ** 3311300Sbill copyblk(v) 33249992Sbostic register Char **v; 3331300Sbill { 33449992Sbostic Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 3351300Sbill 33649992Sbostic return (blkcpy(nv, v)); 3371300Sbill } 3381300Sbill 33949992Sbostic #ifndef SHORT_STRINGS 34049992Sbostic char * 3411300Sbill strend(cp) 34249992Sbostic register char *cp; 3431300Sbill { 34449992Sbostic if (!cp) 3451300Sbill return (cp); 34649992Sbostic while (*cp) 34749992Sbostic cp++; 34849992Sbostic return (cp); 3491300Sbill } 3501300Sbill 35149992Sbostic #endif /* SHORT_STRINGS */ 35249992Sbostic 35349992Sbostic Char * 3541300Sbill strip(cp) 35549992Sbostic Char *cp; 3561300Sbill { 35749992Sbostic register Char *dp = cp; 3581300Sbill 35949992Sbostic if (!cp) 3601300Sbill return (cp); 36149992Sbostic while (*dp++ &= TRIM) 36249992Sbostic continue; 36349992Sbostic return (cp); 3641300Sbill } 3651300Sbill 36649992Sbostic void 3671300Sbill udvar(name) 36849992Sbostic Char *name; 3691300Sbill { 3701300Sbill 37149992Sbostic setname(short2str(name)); 37249992Sbostic stderror(ERR_NAME | ERR_UNDVAR); 3731300Sbill } 3741300Sbill 37549992Sbostic int 3761300Sbill prefix(sub, str) 37749992Sbostic register Char *sub, *str; 3781300Sbill { 3791300Sbill 38049992Sbostic for (;;) { 38149992Sbostic if (*sub == 0) 38249992Sbostic return (1); 38349992Sbostic if (*str == 0) 38449992Sbostic return (0); 38549992Sbostic if (*sub++ != *str++) 38649992Sbostic return (0); 38749992Sbostic } 3881300Sbill } 389