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*60237Schristos static char sccsid[] = "@(#)misc.c 5.19 (Berkeley) 05/22/93"; 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 = ""; 5951437Sleres for (p = s; *p++;) 6051437Sleres continue; 6149992Sbostic n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char))); 62*60237Schristos while ((*p++ = *s++) != '\0') 6351437Sleres continue; 6449992Sbostic return (n); 6517511Sedward } 6617511Sedward 6749992Sbostic Char ** 6849992Sbostic blkend(up) 6949992Sbostic register Char **up; 701300Sbill { 711300Sbill 7249992Sbostic while (*up) 7349992Sbostic up++; 7449992Sbostic return (up); 751300Sbill } 761300Sbill 7717511Sedward 7849992Sbostic void 7950439Schristos blkpr(fp, av) 8050439Schristos FILE *fp; 8149992Sbostic register Char **av; 821300Sbill { 831300Sbill 8449992Sbostic for (; *av; av++) { 8551589Schristos (void) fprintf(fp, "%s", vis_str(*av)); 8649992Sbostic if (av[1]) 8750439Schristos (void) fprintf(fp, " "); 8849992Sbostic } 891300Sbill } 901300Sbill 9149992Sbostic int 921300Sbill blklen(av) 9349992Sbostic register Char **av; 941300Sbill { 9549992Sbostic register int i = 0; 961300Sbill 9749992Sbostic while (*av++) 9849992Sbostic i++; 9949992Sbostic return (i); 1001300Sbill } 1011300Sbill 10249992Sbostic Char ** 1031300Sbill blkcpy(oav, bv) 10449992Sbostic Char **oav; 10549992Sbostic register Char **bv; 1061300Sbill { 10749992Sbostic register Char **av = oav; 1081300Sbill 109*60237Schristos while ((*av++ = *bv++) != NULL) 11049992Sbostic continue; 11149992Sbostic return (oav); 1121300Sbill } 1131300Sbill 11449992Sbostic Char ** 1151300Sbill blkcat(up, vp) 11649992Sbostic Char **up, **vp; 1171300Sbill { 1181300Sbill 11949992Sbostic (void) blkcpy(blkend(up), vp); 12049992Sbostic return (up); 1211300Sbill } 1221300Sbill 12349992Sbostic void 1241300Sbill blkfree(av0) 12549992Sbostic Char **av0; 1261300Sbill { 12749992Sbostic register Char **av = av0; 1281300Sbill 12949992Sbostic if (!av0) 13049992Sbostic return; 13149992Sbostic for (; *av; av++) 13249992Sbostic xfree((ptr_t) * av); 13349992Sbostic xfree((ptr_t) av0); 1341300Sbill } 1351300Sbill 13649992Sbostic Char ** 1371300Sbill saveblk(v) 13849992Sbostic register Char **v; 1391300Sbill { 14049992Sbostic register Char **newv = 14149992Sbostic (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 14249992Sbostic Char **onewv = newv; 1431300Sbill 14449992Sbostic while (*v) 14549992Sbostic *newv++ = Strsave(*v++); 14649992Sbostic return (onewv); 1471300Sbill } 1481300Sbill 14950011Schristos #ifdef NOTUSED 15049992Sbostic char * 15149992Sbostic strstr(s, t) 15249992Sbostic register char *s, *t; 15349992Sbostic { 15449992Sbostic do { 15549992Sbostic register char *ss = s; 15649992Sbostic register char *tt = t; 15749992Sbostic 15849992Sbostic do 15949992Sbostic if (*tt == '\0') 16049992Sbostic return (s); 16149992Sbostic while (*ss++ == *tt++); 16249992Sbostic } while (*s++ != '\0'); 16350024Schristos return (NULL); 16449992Sbostic } 16549992Sbostic 16650011Schristos #endif /* NOTUSED */ 16749992Sbostic 16849992Sbostic #ifndef SHORT_STRINGS 16949992Sbostic char * 1701300Sbill strspl(cp, dp) 17149992Sbostic char *cp, *dp; 1721300Sbill { 17349992Sbostic char *ep; 17449992Sbostic register char *p, *q; 1751300Sbill 17649992Sbostic if (!cp) 17749992Sbostic cp = ""; 17849992Sbostic if (!dp) 17949992Sbostic dp = ""; 18051437Sleres for (p = cp; *p++;) 18151437Sleres continue; 18251437Sleres for (q = dp; *q++;) 18351437Sleres continue; 18449992Sbostic ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char))); 18551437Sleres for (p = ep, q = cp; *p++ = *q++;) 18651437Sleres continue; 18751437Sleres for (p--, q = dp; *p++ = *q++;) 18851437Sleres continue; 18949992Sbostic return (ep); 1901300Sbill } 1911300Sbill 19249992Sbostic #endif 19349992Sbostic 19449992Sbostic Char ** 1951300Sbill blkspl(up, vp) 19649992Sbostic register Char **up, **vp; 1971300Sbill { 19849992Sbostic register Char **wp = 19949992Sbostic (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 20049992Sbostic sizeof(Char **)); 2011300Sbill 20249992Sbostic (void) blkcpy(wp, up); 20349992Sbostic return (blkcat(wp, vp)); 2041300Sbill } 2051300Sbill 20649992Sbostic Char 2071300Sbill lastchr(cp) 20849992Sbostic register Char *cp; 2091300Sbill { 2101300Sbill 21149992Sbostic if (!cp) 21249992Sbostic return (0); 21349992Sbostic if (!*cp) 21449992Sbostic return (0); 21549992Sbostic while (cp[1]) 21649992Sbostic cp++; 21749992Sbostic return (*cp); 2181300Sbill } 2191300Sbill 2201300Sbill /* 2211300Sbill * This routine is called after an error to close up 2221300Sbill * any units which may have been left open accidentally. 2231300Sbill */ 22449992Sbostic void 2251300Sbill closem() 2261300Sbill { 22749992Sbostic register int f; 2281300Sbill 22949992Sbostic for (f = 0; f < NOFILE; f++) 23050439Schristos if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 23149992Sbostic f != FSHTTY) 23249992Sbostic (void) close(f); 2331300Sbill } 2341300Sbill 23549992Sbostic void 2361300Sbill donefds() 2371300Sbill { 23849992Sbostic (void) close(0); 23949992Sbostic (void) close(1); 24049992Sbostic (void) close(2); 24150439Schristos 24249992Sbostic didfds = 0; 2431300Sbill } 2441300Sbill 2451300Sbill /* 2461300Sbill * Move descriptor i to j. 2471300Sbill * If j is -1 then we just want to get i to a safe place, 2481300Sbill * i.e. to a unit > 2. This also happens in dcopy. 2491300Sbill */ 25049992Sbostic int 2511300Sbill dmove(i, j) 25249992Sbostic register int i, j; 2531300Sbill { 2541300Sbill 25549992Sbostic if (i == j || i < 0) 25649992Sbostic return (i); 25749992Sbostic if (j >= 0) { 25849992Sbostic (void) dup2(i, j); 25950233Schristos if (j != i) 26050233Schristos (void) close(i); 2611300Sbill return (j); 26249992Sbostic } 26349992Sbostic j = dcopy(i, j); 26449992Sbostic if (j != i) 26549992Sbostic (void) close(i); 26649992Sbostic return (j); 2671300Sbill } 2681300Sbill 26949992Sbostic int 2701300Sbill dcopy(i, j) 27149992Sbostic register int i, j; 2721300Sbill { 2731300Sbill 274*60237Schristos if (i == j || i < 0 || (j < 0 && i > 2)) 27549992Sbostic return (i); 27649992Sbostic if (j >= 0) { 27749992Sbostic (void) dup2(i, j); 27849992Sbostic return (j); 27949992Sbostic } 28049992Sbostic (void) close(j); 28149992Sbostic return (renum(i, j)); 2821300Sbill } 2831300Sbill 28449992Sbostic static int 2851300Sbill renum(i, j) 28649992Sbostic register int i, j; 2871300Sbill { 28849992Sbostic register int k = dup(i); 2891300Sbill 29049992Sbostic if (k < 0) 29149992Sbostic return (-1); 29249992Sbostic if (j == -1 && k > 2) 2931300Sbill return (k); 29449992Sbostic if (k != j) { 29549992Sbostic j = renum(k, j); 29649992Sbostic (void) close(k); 29749992Sbostic return (j); 29849992Sbostic } 29949992Sbostic return (k); 3001300Sbill } 3011300Sbill 3021300Sbill /* 3031300Sbill * Left shift a command argument list, discarding 3041300Sbill * the first c arguments. Used in "shift" commands 3051300Sbill * as well as by commands like "repeat". 3061300Sbill */ 30749992Sbostic void 3081300Sbill lshift(v, c) 30949992Sbostic register Char **v; 31049992Sbostic register int c; 3111300Sbill { 31250976Schristos register Char **u; 3131300Sbill 31450976Schristos for (u = v; *u && --c >= 0; u++) 31550976Schristos xfree((ptr_t) *u); 31649992Sbostic (void) blkcpy(v, u); 3171300Sbill } 3181300Sbill 31949992Sbostic int 3201300Sbill number(cp) 32149992Sbostic Char *cp; 3221300Sbill { 32349992Sbostic if (!cp) 32449992Sbostic return(0); 32549992Sbostic if (*cp == '-') { 32649992Sbostic cp++; 32749992Sbostic if (!Isdigit(*cp)) 32849992Sbostic return (0); 32949992Sbostic cp++; 33049992Sbostic } 33149992Sbostic while (*cp && Isdigit(*cp)) 33249992Sbostic cp++; 33349992Sbostic return (*cp == 0); 3341300Sbill } 3351300Sbill 33649992Sbostic Char ** 3371300Sbill copyblk(v) 33849992Sbostic register Char **v; 3391300Sbill { 34049992Sbostic Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 3411300Sbill 34249992Sbostic return (blkcpy(nv, v)); 3431300Sbill } 3441300Sbill 34549992Sbostic #ifndef SHORT_STRINGS 34649992Sbostic char * 3471300Sbill strend(cp) 34849992Sbostic register char *cp; 3491300Sbill { 35049992Sbostic if (!cp) 3511300Sbill return (cp); 35249992Sbostic while (*cp) 35349992Sbostic cp++; 35449992Sbostic return (cp); 3551300Sbill } 3561300Sbill 357*60237Schristos #endif /* SHORT_STRINGS */ 35849992Sbostic 35949992Sbostic Char * 3601300Sbill strip(cp) 36149992Sbostic Char *cp; 3621300Sbill { 36349992Sbostic register Char *dp = cp; 3641300Sbill 36549992Sbostic if (!cp) 3661300Sbill return (cp); 367*60237Schristos while ((*dp++ &= TRIM) != '\0') 36849992Sbostic continue; 36949992Sbostic return (cp); 3701300Sbill } 3711300Sbill 37249992Sbostic void 3731300Sbill udvar(name) 37449992Sbostic Char *name; 3751300Sbill { 3761300Sbill 37751589Schristos setname(vis_str(name)); 37849992Sbostic stderror(ERR_NAME | ERR_UNDVAR); 3791300Sbill } 3801300Sbill 38149992Sbostic int 3821300Sbill prefix(sub, str) 38349992Sbostic register Char *sub, *str; 3841300Sbill { 3851300Sbill 38649992Sbostic for (;;) { 38749992Sbostic if (*sub == 0) 38849992Sbostic return (1); 38949992Sbostic if (*str == 0) 39049992Sbostic return (0); 39149992Sbostic if (*sub++ != *str++) 39249992Sbostic return (0); 39349992Sbostic } 3941300Sbill } 395